2013-06-25 3 views
1

Я заметил, что мой код сломался на -O3, но не на -O2. Я попытался применить флаги один за другим, и я обнаружил, что-finline-function breaks my code

gcc -O1 -finline-functions code.c 

breaks; и

gcc -O1 -fno-inline-functions code.c 

работает.

От «breaks», я имею в виду, что он компилируется, но он работает некорректно.

Где я должен искать эту ошибку? Я могу опубликовать код, но, поскольку он весит 1.5K SLOC, я бы предпочел не опубликовать все это.

Версии:

$ uname -a 
Linux xxxx.xxxx 2.6.18-308.20.1.el5 #1 SMP x86_64 x86_64 x86_64 GNU/Linux 
$ gcc -v 
Using built-in specs. 
Target: x86_64-redhat-linux 
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --disable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux 
Thread model: posix 
gcc version 4.1.2 20080704 (Red Hat 4.1.2-54) 
+0

Вы используете довольно старую версию GCC, попробуйте обновить ее. Вероятно, это проблема с неопределенным поведением или некоторой «магической» функцией, например 'setjmp' /' longjmp'. Попытайтесь найти, какая функция вызывает проблему. –

+1

Если вы можете сузить список функций, которые могут вызывать проблему, вы можете протестировать каждый из них, индивидуально отключив вставку с помощью атрибута [noinline] (http://gcc.gnu.org/onlinedocs/gcc/Function -Attributes.html), пока не найдете фактического виновника. – sjs

+0

Пройдите процесс создания SSCCE ([Short, Self-Contained, Correct Example] (http://sscce.org/)). Когда он минимален, если RedHat все еще поддерживает используемый вами компилятор, вы можете попытаться сообщить о проблеме им. Команда GCC не будет заинтересована в отчете против 4.1.x; они давно отказались от поддержки GCC 4.1.x (согласно http://gcc.gnu.org/, 4.7.x - старейшая поддерживаемая версия). Если вы можете воспроизвести проблему в 4.7.x или (лучше) 4.8.x, тогда вы можете сообщить об этом им. –

ответ

3

Я понял ошибку:

int foo() { 
    return 5; 
} 
int bar() { 
    foo(); // <-- no return statement! 
} 
int main() { 
    printf("%d", bar()); 
} 

Смотрите, несмотря на то, что нет возврата заявление в bar(), значение 5 уже в регистре возвращаемого значения. main() берет значение в регистре возврата, думая, что это от бара, но на самом деле это от foo. Это неопределенное поведение, но оно только взрывается, если компилятор пытается установить inline bar(). Решение состоит в том, чтобы положить возвращение в bar()

к кредитным ССАГПЗ, это делает вас предупредить, если вы включите -Wall

code.c:63: warning: control reaches end of non-void function 

Я нашел это вручную применяя __attribute__ ((noinline)) (спасибо SJS!) К функциям до моего код работал правильно

+0

Это не ошибка в GCC, это просто еще один случай * Undefined Behavior *. –

+0

@AdamRosenfield Не сказал, что это ошибка в gcc. –

+1

Вау! Вы имеете в виду, что вы не компилируете с '-Wall -Wextra' все время? Вы не можете позволить себе не использовать их! –