C标准规定,对于函数定义,如果声明符包含标识符列表,则参数的类型应在以下声明列表中声明。显然这会产生影响。< / p>
extern int max(int a, int b)
{
return a > b ? a : b;
}
extern int max(a, b)
int a, b;
{
return a > b ? a : b;
}
这里是int a,b;是参数的声明列表。该 这两个定义之间的区别在于第一种形式的作用 作为原型声明,强制转换参数 后续调用函数,而第二种形式不调用。
这对程序员意味着什么,它是否会影响编译器生成的代码?
答案 0 :(得分:11)
这意味着在第二种情况下,调用者有责任确保提供的参数类型正确;不会提供隐式转换(默认参数促销除外)。从6.5.2.2节开始:
如果表示被调用函数的表达式具有不包含a的类型 原型,对每个参数执行整数提升。
...
如果表示被调用函数的表达式具有包含原型的类型,则将参数隐式转换为类似于 相应的参数。
所以调用这样的代码就可以了:
char x = 3;
char y = 7;
max(x, y); // Equivalent to max((int)x, (int)y)
因为x
和y
在被放入堆栈之前被提升为int
。
但是,像这样的代码不行:
double x = 3.0;
long y = 7;
max(x, y); // Uh-oh
x
和y
将作为double
和long
放置在堆叠中,但max()
将尝试读取两个int
s ,这将导致未定义的行为(实际上,原始位将被重新解释)。
这是不使用第二种形式的一个原因;它在标准中的唯一原因是提供与(极端)遗留代码的向后兼容性。如果您正在使用GCC,则可以使用-Wold-style-definition
标志强制执行此操作;我希望其他编译器可以提供相同的东西。