0

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

细节表示赞赏。

4

2 回答 2

4

如果编译器没有关于如何传递参数的具体信息,例如当没有原型时,或者在原型有省略号 ('...') 的情况下传递的参数时,编译器会遵循某些传递规则论据。这些规则基本上遵循在使用原型之前在准标准(或 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

在应用这些默认参数提升后,参数被简单地复制到编译器通常复制参数的位置(通常是堆栈)。因此,结构参数将被复制到堆栈中。

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

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

于 2011-06-27T04:37:49.150 回答
3

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

于 2011-06-27T03:56:22.223 回答