"internal linkage"是什么意思?
What does "internal linkage" mean?
标准中说:
当一个名称具有内部链接时,它所表示的实体可以是由同一翻译单元中其他作用域的名称引用。
:
具有命名空间作用域(3.3.6)的名称具有内部链接变量、函数或函数模板的名称显式声明static;
考虑下面的代码:
#include <stdio.h>
namespace A
{
/* a with internal linkage now.
Entity denoted by a will be referenced from another scope.
This will be main() function scope in my case
*/
static int a=5;
}
int main()
{
int a; //declaring a for unqualified name lookup rules
printf("%dn",a);//-1216872448
}
我真的不明白标准中的定义。
是什么意思?中它所表示的实体可以被其他作用域的名称引用相同的翻译单元。
翻译单元通常由单个源文件和所有#include
d文件组成,结果为一个目标文件。
命名空间作用域中的名称在默认情况下具有外部链接,这意味着您可以从其他翻译单元(使用作用域解析操作符或使用指令)引用该名称。但是,如果名称用static
限定,则链接变为内部,并且该名称不能在定义它的翻译单元之外被引用。
在您的示例中,如果名称空间A
,名称a
和main
方法在相同的翻译单元中,则可以访问a
。但是在main
中,您声明了另一个变量a
,它将a
隐藏在名称空间A
中。并且main中的a
没有初始化,所以当你打印时,它实际上打印了main
中声明的a
的垃圾值。如果您想在main
中使用A
中的a
,则在包含main
的源文件中使用cout<<A::a
或using namespace A;
。
"翻译单元"是指编译器一次处理的代码块的技术术语。通常这是一个.cpp
源文件和它包含的所有头文件。
在实践中,这通常意味着翻译单元被编译成一个目标文件。这个目标文件不是完整的程序;它必须与其他目标文件"链接"才能生成最终的程序。"链接"过程就是简单地将在一个翻译单元中定义并在一个或多个其他翻译单元中使用的各种功能进行匹配。
例如,您的翻译单元调用printf
,但是printf
的定义(机器代码)实际上在另一个翻译单元中。所以链接器必须知道1)printf
的实际定义在哪里,2)它在代码中的调用位置,这样它就可以将1)的地址插入到2)中。
printf
是具有外部链接的事物的一个例子;它可以链接到其翻译单元外部的事物。另一方面,具有内部链接的内容只能在其翻译单元内链接。因此,在您的示例中,main
可以访问在名称空间级别声明为static
的A::a
,但是在该翻译单元之外定义的函数无法看到A::a
。这是因为编译器从object文件的链接表中省略了对A::a
的引用。
最后,在你的例子中发生的是,main
看到的a
是它在自己内部声明的,它是未初始化的。这就是为什么它打印了一个垃圾值。如果您将main
更改为:
int main()
{
printf("%dn", A::a);
}
它将打印5
它所表示的实体可以被同一翻译单元中其他作用域的名称引用。
为了使这一点有意义,你必须理解实体和名称之间的区别。
在main函数中,您创建了一个新实体,并将其命名为a
。该名称不是指名称空间a中称为a
的同一实体,它是一个不同的实体,不仅因为它具有不同的链接,还因为它位于不同的名称空间。
局部变量默认没有链接,因此它们总是指定一个新的实体。例如
static int a = 5; // a new entity with name `a` that has internal linkage.
int main()
{
int a; // This is a new entity local to function main with no linkage.
// It isn't initialized, so you have undefined behavior if you try to
// access it.
}
在这种情况下,您有两个实体,都命名为a
,但它们引用不同的实体,因为它们在不同的作用域中具有不同的链接。
标准所指的情况是这样的:
static int a = 5; // A new entity with the name `a` that has internal linkage.
void f()
{
extern int a; // This is a new declaration for the same entity called `a` in
// the global scope.
}
现在您只有一个实体,但是在两个不同的作用域中仍然有两个名称。这两个名字指的是同一个实体。
这是一个非常棘手的问题。因为f()
内部的声明有extern
,所以您说您希望f的a
引用在其他地方定义的实体。然而,由于a
在全局作用域中已经声明为static
,这使得a
具有内部链接而不是外部链接。
请注意,对于具有内部链接的同一实体使用两个名称并没有太大的实际价值,因为您总是可以使用第一个名称来代替。
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- "类模板示例<int>;"语句对 C++11 是什么意思?
- 线应该是什么意思
- 错误:无效的预处理指令 #i 的意思是 #if?
- "CID"在AT+HTTPPARA= "CID" ,1中是什么意思
- 表达式"b=(b-x)&x"是什么意思?
- 这个表达是什么意思?
- 此代码验证公式是什么意思?
- 跟踪日志中的T.11803()是什么意思?
- Trie*& 和 Trie** 的意思是 Same?
- 这个额外的关键字在这个 c++ 类声明中是什么意思?
- 错误:无法解析对重载函数的引用;你的意思是调用它吗?
- * 和 ** 在 C++ 函数声明中是什么意思?
- _T("xyz")是什么意思?
- #define Dbg(fmt,..) (0) 是什么意思? 警告:表达式无效
- 这行代码到底是什么意思?
- 在命名空间名称之前加上 :: 是什么意思?
- 从字符数组的元素中减去'a'是什么意思
- "internal linkage"是什么意思?