为什么非外部代码可以在C/C ++中的.h文件中? [英] Why can non-extern be in .h files in C/C++?

查看:82
本文介绍了为什么非外部代码可以在C/C ++中的.h文件中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此文件为例,有很多非-extern结构,例如:

Take this file as example,there are many non-extern structures like:

struct list_head source_list;

当多个编译单元包含此头文件时,它如何工作?

How can it work when this header file is included by more than one compile units?

应该有错误报告,两次定义了相同的符号,对吗?

There should be error reporting that the same symbol is defined twice,right?

推荐答案

从技术上讲应该可以使用,但是这种用法已经存在了多年,并且无法根除(已经尝试过;每隔一段时间,某些供应商就会决定使其成为错误. ,并在前一百个错误报告后恢复).在脚下,.h文件应声明为extern一个 .c/.cpp文件应对其进行定义.

Technically there should, but that usage has been around for years and is impossible to eradicate (it's been tried; every so often some vendor decides to make it an error, and reverts after the first hundred or so bug reports). Pedantically, the .h file should declare it extern and one .c/.cpp file should define it.

简而言之,当您不指定顶级变量的链接(staticextern等)时,将其声明为公共".在链接时,如果对该变量的所有引用都具有相同的大小(和类型,如果可用),则该变量将被分配一次,并且所有引用都指向该变量.如果链接器发现同一变量的大小/类型/链接不同,则会引发错误.

Briefly, when you don't specify the linkage (static, extern, etc.) of a top level variable, it's declared as "common". At link time, if all references to that variable are the same size (and type, when available) then it is allocated once and all references are made to point to it. If the linker finds different sizes / types / linkages for the same variable, it throws an error.

这显然使人感到困惑.在这里:

this is clearly confounding people. Here:

jinx:1714 Z$ cat foo.h
int foo;
extern void bar();
jinx:1715 Z$ cat foo.c
#include "foo.h"

int
main(int argc, char **argv)
{
  bar();
  return 0;
}
jinx:1716 Z$ cat bar.c
#include "foo.h"

void
bar(void)
{
  return;
}
jinx:1717 Z$ gcc -Wall foo.c bar.c -o foo
jinx:1718 Z$ ./foo
jinx:1719 Z$ _

请注意,完全没有关于int foo被多重定义的错误. 是我一直想说的.

Note the complete lack of errors about int foo being multiply defined. This is what I've been trying to say.

这篇关于为什么非外部代码可以在C/C ++中的.h文件中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆