2015-10-02 2 views
1

Название файла программы - armstrong3.c.Необычное поведение pow() в C во время компиляции

#include <stdio.h> 
#include <math.h> 

int main(void) { 
int i, sum, num, rem,x; 
x=pow(2,5); 
printf("%d\n", x); 
printf("List of 3 digit armstrong numbers \n"); 
for (i=100; i<=999; i++) { 
    num=i; 
    sum=0; 
    while (num>0) { 
     rem=num%10; 
     sum=sum+pow(rem,3); 
     num/=10; 
    } 
    if (i==sum) 
     printf("%d\n", i); 
    } 
return 0; 
} 

Эта простая программа находит 3-хзначные цифры в армстронге. Для вычисления куба я использую pow() из math.h. Он не работал изначально и дал известную ошибку во время компиляции:

armstrong3.c:(.text+0x91): undefined reference to `pow' collect2:

error: ld returned 1 exit status.

Тогда я скомпилировал с gcc armstrong.c -lm, и она работала хорошо.

Затем я использовал еще одну функцию pow() во второй строке функции main() и прокомментировал более раннюю функцию pow(), которую я использовал для вычисления куба. Как ни странно, программа скомпонована с gcc armstrong3.c.

Программа, отправленная мной, компилируется с использованием gcc armstrong.c -lm.

Следующий сценарий мой текущий вопрос:

Со вторым pow() закомментированного он gcc armstrong.c компилируется без каких-либо предупреждений и ошибок. № -lm требуется флаг.

Если я раскомментирую вторую функцию pow() в программе, она не компилируется и не дает вышеупомянутую ошибку. И с -lm он отлично работает.

Почему это необычное поведение с той же функцией в двух местах внутри одной и той же программы?

Компилятор: gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1 ~ 14.04).

+0

См. [Log (10.0) может компилироваться, но log (0.0) не может?] (Http://stackoverflow.com/q/24294578/1708801). В основном gcc может оптимизировать вызовы некоторых встроенных функций при использовании аргументов постоянного выражения. Попробуйте использовать '-fno-builtin' –

ответ

1

Это поведение вызвано введением результата функции pow в случае постоянных выражений в его вызове.

+0

Есть ли ссылка, документирующая это поведение' gcc'? – rootkea

+0

@rootkea: Я не знаю о такой ссылке, но это должно быть легко проверить, проверяя сгенерированный код. –

+0

@rootkea Для этого вам не нужна специальная документация. Компилятор знает, как работает эта функция (потому что это стандартная функция C), и имеет полное право заменить вызов лучшим эквивалентом, константой в этом случае. –

4

Then I used another pow() function in the second line of the main() function and commented out the earlier pow() function which I was using to calculate the cube. Strangely, the program compiled fine with gcc armstrong3.c.

pow - это внутренняя функция. Когда вы указываете все свои аргументы как константы времени компиляции, как в pow(2, 5), компилятор заменяет вызов своим значением.

Это происходит только для целых аргументов. Потому что, когда вы передаете аргументы с плавающей запятой, результат pow зависит от текущего floating point rounding mode, который не известен во время компиляции.