为什么const在C ++中隐含内部链接,而在C中却不隐含?


82

参见主题。他们在想什么?

更新:从“静态”更改为“内部链接”以节省混乱。

举个例子...将以下内容放入文件中:

const int var_a = 1;
int var_b = 1;

...并且g++ -c test.cpp仅使用出口进行编译var_b

Answers:


112

我相信你的意思

为什么const暗示C ++中的内部链接

的确,如果在名称空间范围内声明const对象,则它具有内部链接。

附录C(C ++ 11,C.1.2)给出了基本原理

更改:显式声明为const而不显式声明为extern的文件范围的名称具有内部链接,而在C中它将具有外部链接

原理:由于const对象可用作C ++中的编译时值,因此此功能敦促程序员为每个const提供显式的初始化程序值。此功能允许用户将const对象放入许多编译单元中包含的头文件中。


似乎非const全局对象也可以初始化,但是为什么standard不给它内部链接?
勇力

13

正如litb所说,const对象在C ++中具有内部链接。这是因为它们打算像这样使用:

// a.cpp
const int BUFSIZE = 100;
char abuf[BUFSIZE];

// b.cpp
const int BUFSIZE = 256
int bbuf[BUFSIZE];

6

在C和C ++中,const和static是正交的概念。

const关键字告诉编译器从呈现为任何表达的左值禁止可变-基本上使它只读的。

在C语言中,static关键字有多种用途,具体取决于它所应用的对象。当将其应用于函数的变量时,它表示该变量未存储在函数的本地范围内,但可在调用该函数时访问。当应用于全局变量或函数时,它仅可用于特定文件-换句话说,它仅可在编译单元内访问(除非声明extern)。

在C ++中,static可以在类定义中使用关键字,以使变量或函数在类的所有实例之间共享,而不是在每个实例中都位于局部。此外,C ++中的静态类函数只能访问该类(或它有权访问的类)的静态变量。现在,在C ++中const确实为成员提供了到编译单元的内部链接,除非明确声明了它们extern-这可能就是您所引用的。这允许通过使用头文件在整个单元之间共享编译时常量。但是请记住,成员并不是真正的静态对象-而是将常量编译到引用它的每个位置。


6

在C&C ++中,静态一词具有多种含义(它可以控制链接和存储)您必须阅读Stroustrup的D&E才能理解他的基本原理-但是,当您在名称空间范围内将变量声明为const时,它会自动具有内部链接-而在C中,您必须将其声明为静态,以使其具有内部链接。

当然,在C ++中,不建议使用静态方法来控制链接,可以使用匿名名称空间来模拟C ++中的内部链接。

应该用C ++中的const变量替换预处理器常量-并且由于预处理器常量仅在定义它们的文件中可见,因此类似地,const自动使该变量仅在定义它的文件中可见。


4

这些概念是正交的,不应视为同一事物。

常量是一种访问权限:它仅告诉您变量是只读(const)还是可读写(非const)。

静态性是生命周期(从技术上讲是内存本地化)属性:它指示变量是在类范围内(在类中)还是在翻译单元中(与在cpp中定义的全局变量一起使用时)是全局性的。


-2

事实并非如此,最明显的例子是,如果您有一个const成员变量(当然是由构造函数初始化的),那么该类的所有对象都不共享它,而是每个对象都共享它。

class A {
public:
  A(int newx) : x(newx);
private
  int x;
}

在上面,litb给出了最佳答案。


他不是总是吗?(litb)
RastaJedi

-5

没有。编写以下内容:

const int i = 0;

不会使i静态(在C或C ++中)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.