隐含的功能声明

时间:2011-06-27 03:51:20

标签: c gcc compiler-construction gcc-warning

当未包含正确的头文件时,GCC通常会产生此警告。这个链接 - > www.network-theory.co.uk/docs/gccintro/gccintro_19.html表示因为函数声明是隐式的(而不是通过标头显式声明),实际上可能会将错误的参数类型传递给函数,从而产生不正确的结果。我不明白这一点。这是否意味着编译器生成的代码将机器的字大小推送到堆栈上以供被调用者使用,并希望最好?

详情请见。

2 个答案:

答案 0 :(得分:3)

在经典的K& R C中,这几乎就是发生的事情;有默认的强制(例如,小于(int)的任何东西被提升为(int)),并且为了向后兼容,任何没有原型的函数仍然以这种方式调用,但总的来说,这是你得到的唯一指示传递错误的类型是一个奇怪的结果或可能是核心转储。这就是你遇到麻烦的地方,因为当函数有一个原型时,推送了确切的(非强制/提升)值。因此,如果您传递(char),如果范围内有原型,则调用者将推送单个字节,否则为4个字节(在大多数当前平台上)。如果来电者和被叫者不同意这一点,就会发生坏事。

答案 1 :(得分:3)

如果编译器没有关于如何传递参数的特定信息,例如当没有原型或者在原型具有省略号('...')的情况下传递的参数时,编译器会遵循某些传递参数的规则。这些规则基本上遵循预标准(或K& R)C中发生的情况 - 在使用原型之前。转述自C99 6.5.2.2/6“函数调用”:

* the integer promotions are applied
* if the argument has float type it's promoted to double

在应用这些默认参数提升后,只需将参数复制到编译器通常复制参数(通常是堆栈)的任何位置。因此,struct参数将被复制到堆栈中。

如果实际的函数实现与编译器创建参数的方式不匹配,那么就会得到未定义的行为(如果值可以表示为有符号/无符号不匹配,或者指向char的指针和指向void的指针可以混合/匹配的)。

同样在C90中,如果隐式声明了该函数(C99不允许,但它确实允许没有原型的函数),则返回值默认为int。再一次,实际函数返回其他东西,未定义的行为结果。