const and global



此代码将在c++中产生错误

// Foo.cpp
const int Foo = 99;
// Main.cpp
extern const int Foo;
int main()
{
    cout << Foo << endl;
    return 0;
}    

许多人给出的原因是全局常量具有内部作用域,并且它是默认的静态常量。

解决方案是:-

    //Foo.h
    extern const int Foo; 
    // Foo.cpp
    #include "Foo.h"
    const int Foo = 99; 
    // Main.cpp
    #include "Foo.h"
    int main()
    {
       cout << Foo << endl;
    }

我曾经认为extern是用来告诉编译器,缩进的内存已经分配到其他文件中的某个地方了
在上面的代码上应用相同的逻辑,有人能解释这里发生了什么吗?或者extern在c++中有不同的含义
在此处输入链接描述
再想想这一页,它破坏了我所有的直觉。。

如果我们必须只声明一个全局常量(而不是static)怎么办?extern如何帮助做到这一点

extern限定符声明的const对象具有外部链接
因此,如果您想在多个翻译单元中使用const,请添加一个extern限定符

虽然全局变量默认具有外部链接,但为什么常量全局默认具有内部链接

参考:
C++03标准附录C兼容性C.1.2第3条:基本概念

更改:明确声明为const而未明确声明为extern的文件作用域的名称具有内部链接,而在C中则具有外部链接

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


通过遵循一个简单的规则来避免混淆:

默认情况下,对于非常量符号,Linkage是外部的,对于常量符号,它是静态的(内部的)。

一个快速提醒,让我们清楚地了解我们在谈论什么:

int const a;            //  illegal
int const a = 42;       //  definition, internal linkage
extern int const a;         //  declaration, external linkage
extern int const a = 42;    //  definition , external linkage

注意,如果没有const,上面的前两个声明都是具有外部链接的定义。这绝不是正交的,而且不是很直观,但这是目前的规则所说的。

给出const外部链接的问题在于具有外部链接的对象只有一个定义,并且只有一个异常,只有定义可以具有初始值设定项。这意味着对于具有外部链接的常量,实际值(如果const将用于常量表达式)只能在一个表达式中可见翻译单位。这可能是给予const的动机默认情况下为内部链接。

当然,这至少会导致模板问题层出不穷理论上;以下标头具有未定义的行为(如果是)包括在多个翻译单元中:

#include <std::vector>
int const fixedValue = 42;
inline void insertFixedValue( std::vector<int>& dest )
{
    dest.push_back( fixedValue );
}

该标准规定,内联函数和模板不仅必须具有相同的令牌序列,但所有符号都必须绑定到每个翻译单元中的同一对象,或者违反一个定义规则。由于fixedValue没有外部链接,在每个翻译单元中都有一个唯一的实例。(有异常如果符号引用const对象并且存在立即从左值到右值的转换。自从CCD_,没有立即的左值到右值的转换,我们得到了未定义行为。)

当然,任何有模板的人:

template <int& r> ...

也不能用fixedValue实例化它。

内部联系的原因当然是历史性的。今天编译器必须能够支持以下内容:

struct X
{
    static int const a = 42;    //  declaration!!!, external linkage
};

以及各种重复的函数定义。会的扩展允许在类中对命名空间范围内的变量的声明类似于:

int const a;                //  illegal
int const a = 42;           //  definition, external linkage
extern int const a;         //  declaration, external linkage
extern int const a = 42;    //  declaration, external linkage

这将恢复正交性(即使需要额外的类型)。它也会破坏几乎所有现有的代码。

另一种选择是处理const变量定义正如今天处理的函数模板一样:您可以有多个定义,但它们必须完全相同。这可能会避免大部分(如果不是全部的话)代码破坏。

相关内容

  • 没有找到相关文章