О релизах и багах
Модератор: Модераторы
-
PVOzerski
- постоялец
- Сообщения: 109
- Зарегистрирован: 19.05.2005 13:45:10
- Откуда: СПб
- Контактная информация:
В продолжение разговора о смартлинке и .edata в Win32:
IMHO, следует иметь в виду следующее: при компиляции под смартлинк компилятор делает из юнита coff-библиотеку, притом если не включено использование внешнего ассемблера, то не задействуется даже библиотекарь ar. Если, Иван, идти твоим путем (принудительная прилинковка модуля с .edata с помощью явного его указания линкеру), придется либо придумывать особый режим генерации для этого модуля (IMHO, это не самая простая задача, с учетом структурной организации FPC), либо извлекать нужный obj-файл из библиотеки перед линковкой (что выглядит кривовато). Может, лучше всё-таки починить проверенный вариант с меткой?
IMHO, следует иметь в виду следующее: при компиляции под смартлинк компилятор делает из юнита coff-библиотеку, притом если не включено использование внешнего ассемблера, то не задействуется даже библиотекарь ar. Если, Иван, идти твоим путем (принудительная прилинковка модуля с .edata с помощью явного его указания линкеру), придется либо придумывать особый режим генерации для этого модуля (IMHO, это не самая простая задача, с учетом структурной организации FPC), либо извлекать нужный obj-файл из библиотеки перед линковкой (что выглядит кривовато). Может, лучше всё-таки починить проверенный вариант с меткой?
- Иван Шихалев
- энтузиаст
- Сообщения: 1138
- Зарегистрирован: 15.05.2006 11:26:13
- Откуда: Екатеринбург
- Контактная информация:
придется либо придумывать особый режим генерации для этого модуля (IMHO, это не самая простая задача, с учетом структурной организации FPC), либо извлекать нужный obj-файл из библиотеки перед линковкой
С какой радости? OBJ для основного файла существует. Надо просто его задействовать, как и при линковке EXE. Извлечение из юнитов же пойдет так же как и для EXE.
Или я не понял вопроса?
-
PVOzerski
- постоялец
- Сообщения: 109
- Зарегистрирован: 19.05.2005 13:45:10
- Откуда: СПб
- Контактная информация:
>OBJ для основного файла существует
Иван, как ты предлагаешь задействовать obj-файл модуля program при смартлинке?
Смотри, что происходит (юзаю один из заключительных билдов 1.9, но вряд ли в 2.0 это сильно иначе):
Вот мы пишем такую прогу:
library test;
procedure proc;export;
begin
end;
exports
proc;
begin
writeln('Hello, world! I has been loaded!');
end.
Вот какой link.res получается при компиляции без смартлинка:
SEARCH_DIR(D:\PAS\fpc102\units\win32\)
SEARCH_DIR(D:\PAS\fpc102\bin\win32\)
INPUT(
D:\PAS\fpc102\units\win32\wdllprt0.o
test.o
)
GROUP(
D:\PAS\fpc102\units\win32\libpSystem.a
)
А вот какой - при смартлинке:
SEARCH_DIR(D:\PAS\fpc102\units\win32\)
SEARCH_DIR(D:\PAS\fpc102\bin\win32\)
INPUT(
D:\PAS\fpc102\units\win32\wdllprt0.o
)
GROUP(
libptest.a
D:\PAS\fpc102\units\win32\libpSystem.a
)
То есть при смартлинке obj-файл главного модуля вообще не прилинковывается.Ты хочешь предложить игнорировать смартлинк для главного модуля и линковать obj-файл вместо библиотеки? А у тебя есть уверенность, что тогда ты сможешь избавиться от всего "мертвого кода", который может в нем содержаться? Вот смотри еще тест. На сей раз это не dll, а экзешник.
procedure TTTT;
begin
writeln('Hello');
end;
begin
end.
Теперь посмотри на asm-код, сделанный компилятором для генерации .o-файла:
.file "tt2.pp"
.section .text
.section .text
.balign 4
.balign 4
.globl P$PROGRAM_TTTT
P$PROGRAM_TTTT:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
movl %ebx,-4(%ebp)
call fpc_get_output
movl %eax,%ebx
movl $_$PROGRAM$_L10,%ecx
movl %ebx,%edx
movl $0,%eax
call fpc_write_text_shortstr
call FPC_IOCHECK
movl %ebx,%eax
call fpc_writeln_end
call FPC_IOCHECK
movl -4(%ebp),%ebx
leave
ret
.section .text
.balign 4
.balign 4
.globl PASCALMAIN
PASCALMAIN:
.globl _main
_main:
pushl %ebp
movl %esp,%ebp
call FPC_INITIALIZEUNITS
call FPC_DO_EXIT
leave
ret
.balign 4
.section .data
.ascii "FPC 1.9.9 [2005/04/27] for i386 - Win32"
.balign 4
.balign 4
.globl THREADVARLIST_P$PROGRAM
THREADVARLIST_P$PROGRAM:
.long 0
.balign 4
.globl FPC_THREADVARTABLES
FPC_THREADVARTABLES:
.long 2
.long THREADVARLIST_SYSTEM
.long THREADVARLIST_P$PROGRAM
.balign 4
.globl FPC_RESOURCESTRINGTABLES
FPC_RESOURCESTRINGTABLES:
.long 0
.balign 4
.globl INITFINAL
INITFINAL:
.long 1,0
.long INIT$_SYSTEM
.long FINALIZE$_SYSTEM
.balign 4
.globl __stklen
__stklen:
.long 262144
.globl __heapsize
__heapsize:
.long 0
.section .data
.section .data
.balign 4
.globl _$PROGRAM$_L10
_$PROGRAM$_L10:
.ascii "\005Hello\000"
.section .data
.section .data
.section .bss
Можно видеть, что "мертвая" процедура TTTT никуда не делась, осталась в коде и должна попасть в конечный экзешник. Конечно, это изъян оптимизатора, но что на данном этапе проще: переделывать оптимизацию или переложить кое-что на линкер?
BTW, я вообще плохо понимаю, чего ради компилятор генерит .o-файл параллельно с библиотекой, если велено компилировать под смартлинк.
Иван, как ты предлагаешь задействовать obj-файл модуля program при смартлинке?
Смотри, что происходит (юзаю один из заключительных билдов 1.9, но вряд ли в 2.0 это сильно иначе):
Вот мы пишем такую прогу:
library test;
procedure proc;export;
begin
end;
exports
proc;
begin
writeln('Hello, world! I has been loaded!');
end.
Вот какой link.res получается при компиляции без смартлинка:
SEARCH_DIR(D:\PAS\fpc102\units\win32\)
SEARCH_DIR(D:\PAS\fpc102\bin\win32\)
INPUT(
D:\PAS\fpc102\units\win32\wdllprt0.o
test.o
)
GROUP(
D:\PAS\fpc102\units\win32\libpSystem.a
)
А вот какой - при смартлинке:
SEARCH_DIR(D:\PAS\fpc102\units\win32\)
SEARCH_DIR(D:\PAS\fpc102\bin\win32\)
INPUT(
D:\PAS\fpc102\units\win32\wdllprt0.o
)
GROUP(
libptest.a
D:\PAS\fpc102\units\win32\libpSystem.a
)
То есть при смартлинке obj-файл главного модуля вообще не прилинковывается.Ты хочешь предложить игнорировать смартлинк для главного модуля и линковать obj-файл вместо библиотеки? А у тебя есть уверенность, что тогда ты сможешь избавиться от всего "мертвого кода", который может в нем содержаться? Вот смотри еще тест. На сей раз это не dll, а экзешник.
procedure TTTT;
begin
writeln('Hello');
end;
begin
end.
Теперь посмотри на asm-код, сделанный компилятором для генерации .o-файла:
.file "tt2.pp"
.section .text
.section .text
.balign 4
.balign 4
.globl P$PROGRAM_TTTT
P$PROGRAM_TTTT:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
movl %ebx,-4(%ebp)
call fpc_get_output
movl %eax,%ebx
movl $_$PROGRAM$_L10,%ecx
movl %ebx,%edx
movl $0,%eax
call fpc_write_text_shortstr
call FPC_IOCHECK
movl %ebx,%eax
call fpc_writeln_end
call FPC_IOCHECK
movl -4(%ebp),%ebx
leave
ret
.section .text
.balign 4
.balign 4
.globl PASCALMAIN
PASCALMAIN:
.globl _main
_main:
pushl %ebp
movl %esp,%ebp
call FPC_INITIALIZEUNITS
call FPC_DO_EXIT
leave
ret
.balign 4
.section .data
.ascii "FPC 1.9.9 [2005/04/27] for i386 - Win32"
.balign 4
.balign 4
.globl THREADVARLIST_P$PROGRAM
THREADVARLIST_P$PROGRAM:
.long 0
.balign 4
.globl FPC_THREADVARTABLES
FPC_THREADVARTABLES:
.long 2
.long THREADVARLIST_SYSTEM
.long THREADVARLIST_P$PROGRAM
.balign 4
.globl FPC_RESOURCESTRINGTABLES
FPC_RESOURCESTRINGTABLES:
.long 0
.balign 4
.globl INITFINAL
INITFINAL:
.long 1,0
.long INIT$_SYSTEM
.long FINALIZE$_SYSTEM
.balign 4
.globl __stklen
__stklen:
.long 262144
.globl __heapsize
__heapsize:
.long 0
.section .data
.section .data
.balign 4
.globl _$PROGRAM$_L10
_$PROGRAM$_L10:
.ascii "\005Hello\000"
.section .data
.section .data
.section .bss
Можно видеть, что "мертвая" процедура TTTT никуда не делась, осталась в коде и должна попасть в конечный экзешник. Конечно, это изъян оптимизатора, но что на данном этапе проще: переделывать оптимизацию или переложить кое-что на линкер?
BTW, я вообще плохо понимаю, чего ради компилятор генерит .o-файл параллельно с библиотекой, если велено компилировать под смартлинк.
- Иван Шихалев
- энтузиаст
- Сообщения: 1138
- Зарегистрирован: 15.05.2006 11:26:13
- Откуда: Екатеринбург
- Контактная информация:
-
PVOzerski
- постоялец
- Сообщения: 109
- Зарегистрирован: 19.05.2005 13:45:10
- Откуда: СПб
- Контактная информация:
Итак, патч для smartlink'а подключен к версии 2.1. Что дальше? Предлагаю на повестку дня ставить поддержку секции Exports в юнитах. Примерный путь реализации - изменение формата PPU-шек с добавлением возможности включения в них информации об экспортируемых элементах (процедурах, функциях, переменных).
- Romtek
- постоялец
- Сообщения: 190
- Зарегистрирован: 22.05.2005 12:29:35
- Откуда: Рамат Ган
- Контактная информация:
Участник volvo877 форума Исходников заметил баг в программе с конструкцией CASE OF :
По заверению другого участника этот код работает без проблем в версии 1.0.10.
По моим наблюдениям есть баг в CASE OF только для булевых выражений:
Я тут столкнулся с непонятным поведением FPC. Допустим, имеется такой код:Код: Выделить всё
var
i, j: integer;
begin
for i := 1 to 10 do
for j := 1 to 10 do
case (odd(i) and odd(j)) of
true : writeln('i and j are ODD numbers');
false: writeln('...')
end;
end.
И при его компиляции (в любом {$mode ...}) я получаю RTE 35, и как следствие - ошибку IDE... В то же время и вот такой код:и даже вот такой:Код: Выделить всё
var good: boolean;
...
good := (odd(i) and odd(j));
case good of
...
endпрекрасно компилируются...Код: Выделить всё
case odd(j) of
...
end;
Я уже было подумал, что FPC не позволяет вычислять выражения в Case, но вот это:тоже компилируется и отрабатывает. Так почему же самая первая программа делает проблемы? Может, кто-нибудь сталкивался с подобным?Код: Выделить всё
function f(x: integer): integer;
begin {...} end;
...
case f(i) + f(j) of
1: writeln('sum = 1');
4: writeln('sum = 4');
end;
Компилятор FPC 2.0.0 (Target - Win32)
По заверению другого участника этот код работает без проблем в версии 1.0.10.
По моим наблюдениям есть баг в CASE OF только для булевых выражений:
Код: Выделить всё
for i := 1 to 10 do
case (odd(i) and odd (i*i)) of
true : writeln (i , 'is ODD number');
false: writeln ('...')
end;- Иван Шихалев
- энтузиаст
- Сообщения: 1138
- Зарегистрирован: 15.05.2006 11:26:13
- Откуда: Екатеринбург
- Контактная информация:
-
balou
-
Nobushige
Простите, пожалуйста, чайника, но...
Правильно ли, что при сборке и исполнении такой вот программы:
program stupid_test;
{$mode objfpc}
uses strings;
var
c:pchar;
begin
c:=StrNew('test');
writeln(c<>Nil);
StrDispose©;
writeln(c<>Nil);
end.
на экран оба раза выводится TRUE?
Не лучше ли исправить в файле strings.pp
procedure strdispose(p : pchar);
на
procedure strdispose(var p : pchar);
?????
С уважением, Nobushige
Правильно ли, что при сборке и исполнении такой вот программы:
program stupid_test;
{$mode objfpc}
uses strings;
var
c:pchar;
begin
c:=StrNew('test');
writeln(c<>Nil);
StrDispose©;
writeln(c<>Nil);
end.
на экран оба раза выводится TRUE?
Не лучше ли исправить в файле strings.pp
procedure strdispose(p : pchar);
на
procedure strdispose(var p : pchar);
?????
С уважением, Nobushige

