加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

隐式声明如何工作

发布时间:2020-12-16 09:48:05 所属栏目:百科 来源:网络整理
导读:当您不包含和使用malloc时,我们会收到隐式声明警告. “警告:内置函数’malloc’的不兼容的隐式声明” 此警告是由于编译器假定malloc定义为int malloc(size),而它是void * malloc(size). 但它如何知道void * malloc(size)?我们没有在头文件中包含任何内容.
当您不包含和使用malloc时,我们会收到隐式声明警告.

“警告:内置函数’malloc’的不兼容的隐式声明”

此警告是由于编译器假定malloc定义为int malloc(size),而它是void * malloc(size).

但它如何知道void * malloc(size)?我们没有在头文件中包含任何内容.那么如何将它与未包含的内容进行比较呢?

之后,我的代码如何工作?它如何找到正确的malloc定义并使用它?

是否有扫描函数定义的序列顺序?

解决方法

当你调用一个从未定义过的函数f时,会发生这样的隐式声明:

int f();

请注意,您仍然可以将参数传递给f,因为它未被声明为int f(void); (这是为了向后兼容K& R C).

因此,编译器不“知道”malloc接收到一个size参数,实际上你可以将它传递给你想要的,它并不关心.

所以,代码工作的纯粹事实就是纯粹的运气.在malloc的情况下,如果代码有效,它只是意味着整数的大小与指针的大小相同 – 不多也不少 – 所以,你仍然可以调用malloc并将其结果赋值给指针,因为没有比特被修剪/丢失.

在编译发生后,在链接阶段找到真正的函数.到目前为止,您的代码已经使用错误的函数原型进行编译.当然,如果链接器无法在其路径中的任何位置找到该函数,则会报告错误并中止所有内容.

对于malloc和其他标准库函数的情况,可能有内置函数来提高性能. gcc甚至可以选择禁用内置函数(-fno-builtin或-fno-builtin-function).来自gcc手册页:

GCC normally generates special code to handle certain built-in
functions more efficiently; for instance,calls to “alloca” may become
single instructions that adjust the stack directly,and calls to
“memcpy” may become inline copy loops. The resulting code is often
both smaller and faster,but since the function calls no longer appear
as such,you cannot set a breakpoint on those calls,nor can you
change the behavior of the functions by linking with a different
library. In addition,when a function is recognized as a built-in
function,GCC may use information about that function to warn about
problems with calls to that function,or to generate more efficient
code,even if the resulting code still contains calls to that
function.

因此,在malloc的特定情况下,这就是编译器“知道”其通常签名的方式.尝试使用gcc编译此代码:

int main(void) {
    char *a = malloc(12,13,14,15);
    return 0;
}

您将看到它将因编译错误而中止:

test.c:3: error: too many arguments to function `malloc'

如果使用选项-fnobuiltin,则错误消失且警告不同:

test.c:3: warning: implicit declaration of function `malloc'

这与您每次使用之前未定义的常规函数??时获得的警告相同,因为现在编译器忽略了他对这些函数的“了解”.此示例使用gcc,但其他编译器将具有类似的行为.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读