Это зависит от компилятора и уровня оптимизации. Самые последние версии GCC, на некоторых общие системах, с некоторыми оптимизациями, способны сделать такую оптимизацию (замену простого printf
с puts
, которым AFAIU является правовыми нормами аппроксимируемости как C99)
Вы должны включить предупреждения при компиляции (например, попробуйте сначала скомпилировать с gcc -Wall -g
, затем отлаживать с gdb
, тогда, когда вы уверены в своем коде скомпилировать его с gcc -Wall -O2
)
BTW, переопределение puts
действительно очень некрасиво, если вы делаете это нарочно (т.е. являются кодирование вашего собственной библиотеки C, а затем вы должны подчиняться стандартам). Вы получаете undefined behavior (см. Также this answer о возможных последствиях UB). На самом деле вам следует избегать переопределения имен, упомянутых в стандарте, если вы действительно не знаете, что вы делаете и что происходит внутри компилятора.
Кроме того, если вы скомпилированы со статической ссылкой, например gcc -Wall -static -O main.c -o yourprog
, я буду держать пари, что компоновщик пожаловался бы (о множественном определении puts
).
Но IMNSHO ваш код не прав, и вы это знаете.
Кроме того, вы можете скомпилировать, чтобы получить ассемблер, например. с gcc -fverbose-asm -O -S
; и вы даже можете попросить gcc
пролить лот из файлов «дампа», с gcc -fdump-tree-all -O
, который может помочь вам понять, что делает gcc
.
Опять же, эта конкретная оптимизация действует и очень полезно : printf
рутина любого LIBC должен «интерпретировать» во время выполнения формат печати строки (обработка %s
... и т.д. специально); это на практике довольно медленно. Хороший компилятор прав, избегая вызова printf
(и заменяя puts
), когда это возможно.
BTW gcc
не является единственным компилятором, выполняющим эту оптимизацию. clang
также.
Кроме того, если вы компилируете с
gcc -ffreestanding -O2 almo.c -o almo
программа almo
показывает Hello world.
Если вы хотите другой фантазии и surprizing оптимизации, попробуйте скомпилировать
// file bas.c
#include <stdlib.h>
int f (int x, int y) {
int r;
int* p = malloc(2*sizeof(int));
p[0] = x;
p[1] = y;
r = p[0]+p[1];
free (p);
return r;
}
с gcc -O2 -fverbose-asm -S bas.c
затем просмотрите bas.s
; вы не увидите никакого звонка до malloc
или до free
(фактически, нет call
машинная инструкция испускается) и снова gcc
: для оптимизации (и так же clang
)!
PS: Gnu/Linux/Debian/Sid/x86-64; gcc
является версия 4.9.1, clang
это версия 3.4.2
Это оптимизация, которая не зависит от варианта оптимизации GCC. – BLUEPIXY
Вопрос помечен как 'c', хотя вызов компилятора предполагает, что код скомпилирован как C++. –
Да, gcc может оптимизировать простую константную строчную печать с 'printf()' to 'puts()', поскольку последняя работает лучше ... поскольку вы заменили стандартную библиотеку puts() локальным символом, вот что вы получить. Если вы используете -O0 вместо -O2, вы должны на самом деле называть 'printf()' – JohnH