【发布时间】:2015-05-24 03:53:12
【问题描述】:
为什么下面的程序运行良好?
int main()
{
int x;
x = foo();
printf("%d",x);
getchar();
return 0;
}
int foo()
{
return 2;
}
而不是这个程序?
//double function(void);
int main(){
double val;
val = function();
printf("%ul\n",val);
}
double function(void){
double num;
num = DBL_MAX;
printf("%ul\n",num);
return num;
}
据我了解,这两种情况下的函数定义在main() 之前都没有。那么为什么在第一种情况下无论如何都会调用该函数,即使编译器在main() 之前没有定义它,而在第二种情况下没有?
【问题讨论】:
-
请注意,旧的 C 标准 (C99) 和当前的 C 标准 (C11) 都说程序应该生成诊断。只有过时的 (C89/C90) 标准允许第一个程序工作,而第二个程序总是失败。如果你喜欢处理损坏的代码,那很好——写到更草率的 C89 标准。宽松的规则是历史的必然。如果没有松懈,标准就不可能成功。但是旧标准已有 15 年的历史,当您使用没有原型的函数时,您应该使用它并让编译器发出警告。如果您的编译器不会,请使用更好的编译器。
-
@JonathanLeffler ,
%ul可以用作double吗? -
在
printf()格式字符串中?不;%ul格式化unsigned int后跟不属于转换规范的字母l。如果您的意思是%lu,则格式为unsigned long。当您将double作为参数列表中的相应值传递时,两者都没有用(甚至不可靠)。 -
@JonathanLeffler,哎呀!我认为
%ul需要unsigned long。我对%ul和%lu感到困惑。那么,如果一个人用%lu打印double,你是说它是UB? -
@CoolGuy:是的,绝对是 UB 尝试使用任何整数格式打印
double。例如,可以想象浮点值在与整数值不同的寄存器中传递,因此当它看到整数格式时,它从完全错误的位置读取。使用 M68k 芯片的计算机用于在 An 寄存器中返回指针,在 Rn 寄存器中返回整数;如果你没有告诉它一个函数返回了一个指针,编译器会生成从错误位置读取的代码。我不记得这些芯片是如何处理浮点返回的。等等。