Ожидается, что выходные данные компилятора будут разными, иногда резко отличающимися для одного и того же источника. Точно так же, как Toyota и Honda разные. Четыре колеса и несколько сидений, конечно, но больше, чем то же самое, когда вы смотрите на детали.
Точно так же один и тот же компилятор с разными параметрами компилятора может и часто будет производить совершенно разные выходные данные для одного и того же исходного кода. Даже для простых программ.
В случае вашей простой программы, которая на самом деле ничего не делает (код не влияет ни на ввод, ни на вывод, ни на что-либо вне функции), хороший оптимизированный компилятор не даст ничего, кроме main: с возвратом случайное число, так как вы не указали возвращаемое значение. На самом деле это должно дать предупреждение или ошибку. Это самая большая проблема, с которой я сталкиваюсь, когда сравниваю вывод компилятора, делая что-то достаточно простое, чтобы увидеть, что они делают, но что-то достаточно сложное, чтобы компилятор делал больше, чем просто предварительно вычисляет ответ и возвращает его.
В случае с x86, о котором вы, я полагаю, говорите, поскольку в наши дни микрокодирование действительно не дает ответа на вопрос «хороший код против плохого кода», в каждом семействе процессоров они меняют внутренности и то, что раньше было Быстро работает медленно, а то, что сейчас быстро, медленно на старом процессоре. Таким образом, для компиляторов, таких как gcc, которые продолжают развиваться с новыми ядрами, оптимизация может быть как общей для всех x86, так и специфичной для конкретного семейства (что приводит к другому коду, несмотря на максимальную оптимизацию).
С новым интересом к дизассемблированию вы продолжите видеть сходства и различия и узнаете, сколько разных способов можно скомпилировать одним и тем же кодом. Различия ожидаются даже для тривиальных программ. И я призываю вас попробовать как можно больше компиляторов. Даже в семействе gcc 2.x, 3.x, 4.x и различных способах его создания будет разный код, который можно рассматривать как один и тот же компилятор.
Хороший или плохой выход - в глазах смотрящего. Люди, которые используют отладчики, захотят, чтобы их код можно было переставлять, а их переменные можно было наблюдать (в порядке написания кода). Это делает очень большой, громоздкий и медленный код (особенно для x86). А когда вы компилируете релиз, вы получаете совершенно другую программу, которую вы до сих пор тратили на отладку без затрат времени. Кроме того, оптимизируя производительность, вы рискуете компилятором оптимизировать то, что вы хотели, чтобы он делал (ваш пример выше, никакая переменная не будет выделяться, никакой код для перехода, даже при незначительной оптимизации). Или, что еще хуже, вы обнаруживаете ошибки в компиляторе, и ваша программа просто не работает (вот почему -O3 не рекомендуется для gcc). Это и / или вы обнаружите большое количество мест в стандарте C, интерпретация которых определяется реализацией.
Неоптимизированный код легче компилировать, так как он немного более очевиден. В случае вашего примера ожидание, что в стеке размещена переменная, настроено какое-то расположение указателя стека, немедленное значение 1 в итоге записывается в это место, очищается стек и возвращается функция. Компиляторам сложнее ошибиться и более вероятно, что ваша программа работает так, как вы хотели. Обнаружение и удаление мертвого кода - это дело оптимизации и
вот где это становится рискованным. Часто риск стоит награды. Но это зависит от пользователя, красота в глазах смотрящего.
Итог, короткий ответ.Ожидаются различия (даже драматические различия).Параметры компиляции по умолчанию варьируются от компилятора к компилятору.Поэкспериментируйте с опциями компиляции / оптимизации и различными компиляторами и продолжайте разбирать свои программы, чтобы получить лучшее представление о языке и используемых вами компиляторах.Пока вы на правильном пути.В случае вывода borland он обнаружил, что ваша программа ничего не делает, никакие входные переменные не используются, никакие возвращаемые переменные не используются и не связаны с локальными переменными, а также не используются глобальные переменные или другие внешние для ресурсов функции.Целое число a и присвоение немедленного являются мертвым кодом, хороший оптимизатор по существу удалит / проигнорирует обе строки кода.Таким образом, он потрудился установить кадр стека, затем очистить его, что не нужно было делать, а затем вернулся.gcc, похоже, настраивает обработчик исключений, который прекрасно работает, даже если в этом нет необходимости, начинайте оптимизацию или используйте имя функции, отличное от main (), и вы должны увидеть другие результаты.