Однако все работает нормально, если я печатаю итоговую сумму в конце.
Это, вероятно, оптимизирующий компилятор эффект (допустимый, согласно стандарту C11 n1570 ).
Поскольку в вашей программе нет видимого побочного эффекта (без printf
), компилятор разрешен (согласно какЕсли правило ), чтобы оптимизировать его в безоперационную программу.
С некоторыми версиями GCC или Clang и некоторыми флагами оптимизации вы могли наблюдать то же самое.Попробуйте скомпилировать свой код с помощью gcc -O3 -S -fverbose-asm
и посмотреть на сгенерированный ассемблерный код (вы увидите пустое сгенерированное main
с GCC 8.1 для Linux / x86-64)
Кто-нибудь знает, чтоможет быть причиной этой проблемы?
Ваш код и ваше неправильное понимание хитрой семантики из C. Реализация ведет себя в соответствии со стандартом C (и ваша программа работает правильно ).
Кстати, даже с printf
теоретически компилятору разрешено оптимизировать вашу программу до простой константы printf
.На практике текущие компиляторы (к сожалению) не настолько умны.
Если вам нужен надежный тест, n
может зависеть от аргументов программы (и вам все равно нужно сохранить printf
, потому что выхотите некоторый видимый побочный эффект) возможно:
unsigned long n = (argc<2)?1000:(unsigned long)atol(argv[1]);
При измерении производительности не забудьте включить оптимизацию в своем компиляторе!
Кстати, через несколько лет (после того, как вы следили заКурсы CS, включая курс по компиляции и / или прочтению Dragon Book ), вы можете попытаться реализовать некоторый плагин GCC , который сможет оптимизировать вашу функцию с явным printf
(но все равно n
инициализируется константой времени компиляции) в main
, просто вызывающий некоторый printf
и выполняющий цикл, вычисляющий total
в во время компиляции (такая оптимизациязаконно).Вы обнаружите, что такая оптимизация занимает много работы (конечно, месяцы, может, годы!) И может , а не применяться ко многим существующим программам, но вы могли бы получить удовольствие от ее реализации.
Если вас интересуют вычисления с плавающей запятой, обязательно прочитайте руководство с плавающей запятой (это сложно).