编译期间C语言中pow()的异常行为

时间:2015-10-02 07:52:49

标签: c gcc pow math.h

程序文件名 - armstrong3.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):未定义引用`pow'collect2:

     

错误:ld返回1退出状态。

然后我用gcc armstrong.c -lm编译它,它运行正常。

然后我在pow()函数的第二行使用了另一个main()函数,并注释掉了我用来计算多维数据集的早期pow()函数。奇怪的是,程序编译得很好gcc armstrong3.c

我发布的程序可以使用gcc armstrong.c -lm进行编译。

以下情况是我目前的问题:

第二个pow()注释掉它gcc armstrong.c编译时没有警告和错误。无需-lm标志。

如果我取消注释程序中的第二个pow()函数,则它不会编译并给出上述错误。使用-lm它可以正常工作。

为什么在同一程序中的两个地方有相同功能的这种异常行为?

编译器:gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04)。

2 个答案:

答案 0 :(得分:4)

  

然后我在main()函数的第二行使用了另一个pow()函数,并注释掉了我用来计算多维数据集的早期pow()函数。奇怪的是,该程序使用gcc armstrong3.c编译得很好。

pow是一个内在的功能。当您将其所有参数指定为编译时常量时,如pow(2, 5)中所述,编译器将使用其值替换调用。

只有整数参数才会发生。因为当您传递浮点参数时,pow的结果取决于当前floating point rounding mode,这在编译时是未知的。

答案 1 :(得分:1)

如果在调用中出现常量表达式,则内联pow函数结果会导致此行为。