Возможно, я тогда не пересобрал menuetlibc.
В приведённом фрагменте ещё баг: если программа вызывается без параметров, то argc=0, а если с 1 параметром, то сразу argc=2.
Почему-то мне кажется, что это всё уже обсуждалось на форуме, но не могу найти где именно...
Jaeger
Протрассировал в mtdbg твой вчерашний файл до вызова tp_args(). Ошибок нет. Командная строка разбирается на параметры и значение argс устанавливается правильно. адрес argv в памяти 03b008.
Это не баг gcc, что 64-битная версия при компиляции 32-битного кода ругается на совершенно нормальные в 32-битном мире опции? Это не проблема gcc, что он генерирует ужасный код? newlibc вроде не передаёт argc/argv, поэтому там проблема не проявляется, но это не значит, что её нет. Если в функции main компилятор вставляет такой пролог, что ему только и остаётся, что пихать argc/argv в регистры а невезучий программист не вовремя инициализирует консоль, то соответствующий аргумент обязательно испортится.
Раньше сентября не смогу проверить, действительно ли виноват в таком безобразии gcc. Исходный код и все прочее лежит на ноуте, который сейчас очень далеко от меня. Впрочем, исходники вот: download/file.php?id=2311
Можно скомпилить их на сервере и посмотреть, все ли будет ОК.
In file included from main.c:9:
console.c:26: error: 'printf' redeclared as different kind of symbol
/home/autobuild/localcopy/programs/develop/libraries/menuetlibc_/include/stdio.h:95: error: previous declaration of 'printf' was here
console.c:26: error: 'printf' redeclared as different kind of symbol
/home/autobuild/localcopy/programs/develop/libraries/menuetlibc_/include/stdio.h:95: error: previous declaration of 'printf' was here
console.c:28: error: 'gets' redeclared as different kind of symbol
/home/autobuild/localcopy/programs/develop/libraries/menuetlibc_/include/stdio.h:93: error: previous declaration of 'gets' was here
console.c:28: error: 'gets' redeclared as different kind of symbol
/home/autobuild/localcopy/programs/develop/libraries/menuetlibc_/include/stdio.h:93: error: previous declaration of 'gets' was here
CleverMouse wrote:newlibc вроде не передаёт argc/argv
В смысле не передаёт ?
Традиционную разбивку командной строки не делает.
gcc не виноват что void __stdcall con_init() затирает ebx и esi нарушая соглашение о передаче параметров.
Gcc поддерживает примерно 40 архитектур. Очень может быть, что icc сгенерирует код получше. И опять, есть соглашения о передаче параметров. Компилятор не может свободно жонглировать регистрами, как это делает программист. Хотя некоторое движение в этом направлении есть.
Если действительно передаёт, значит, я ошиблась. В любом случае, argc/argv портятся кодом в main и вызываемых функциях независимо от того, насколько корректными они изначально были.
gcc виноват в том, что он генерирует код, для которого это существенно - остальные, включая gcc3 и msvc, как-то до сих пор писали и не натыкались. icc в этом плане - "а вдруг какая-нибудь далёкая функция в каком-нибудь неизвестном файле использует локальную SSE-переменную, требующую выравнивания? давайте выровняем стек прямо в main и дальше будем следить, что он остаётся выровненным, и плевать на размер бинарника и используемую память" - ещё хуже, если уж сравнивать, то с msvc, он хотя бы следит за приличиями.
Это же не FASM с его сборкой из исходников. А если я подключаю libavcodec.a с её LOCAL_ALIGNED_16? Потом жаловаться на то, что тупой gcc не выровнял стек ? Ну от ffmpeg ещё можно ожидать разного SSE-свинства, но команды могут встретится там, где и не подозреваешь.
CleverMouse wrote:gcc виноват в том, что он генерирует код, для которого это существенно
То есть gcc виноват в том что пытается оптимизировать код и не обрамляет каждый вызов pushad popad ?
Компилятор генерирует код следуя ABI и не отвечает за функции нарушающие правила. MSVC использует такой же ABI, за исключением FPU/SSE. То что ошибка не проявляется ещё не значит что она не появится при небольшой модификации кода.
То есть gcc виноват в том, что вместо банальных [ebp+8],[ebp+12] из-за кривого пролога вынужден использовать регистры.
Для libavcodec.a с LOCAL_ALIGNED_16 можно и явно включить опцию -mpreferred-stack-boundary=4. Но gcc мало того, что делает это по умолчанию, так ещё и не позволяет явно уменьшить - и последнее есть совершенно конкретный баг gcc4.
Может баг, а может фича. Сейчас любая большая программа тянет за собой с десяток библиотек. Особенно в Никсах с их сложными зависимостями. По этой причине gcc может принудительно выравнивать стек на ia32.
Spoiler:Fplay main()