简体   繁体   English

extern如何在名称空间中工作?

[英]How does extern work in namespaces?

I'm running a simple program similar to what I found here . 我正在运行一个类似于我在这里找到的简单程序。 It's meant to reduce code bloat when including constants in multiple files. 这意味着在多个文件中包含常量时减少代码膨胀。 It does this by using const global variables within a namespace with their respective extern forward declarations. 它通过在命名空间中使用const全局变量及其各自的extern前向声明来实现此目的。

globals.h globals.h

#ifndef GLOBALS_H_
#define GLOBALS_H_

namespace Constants
{
    // forward declarations only
    extern const double pi;
    extern const double avogadro;
    extern const double my_gravity;
}

#endif

globals.cpp globals.cpp

namespace Constants
{
    // actual global variables
    extern const double pi(3.14159);
    extern const double avogadro(6.0221413e23);
    extern const double my_gravity(9.2); // m/s^2 -- gravity is light on this planet
}

source.cpp source.cpp

#include <iostream>
#include <limits>

#include "globals.h"

int main()
{
    double value_of_pi = Constants::pi;

    std::cout << value_of_pi;

    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    std::cin.get();

    return 0;
}

I assume that Constants::pi gets the value pi contained in the globals.cpp Constants namespace, and is able to do so because it has access to the namespace itself from the included globals.h. 我假设Constants :: pi获取globals.cpp Constants命名空间中包含的值pi,并且能够这样做,因为它可以从包含的globals.h访问命名空间本身。 What I don't understand is why the const global definitions/initializations in globals.cpp need the extern keyword? 我不明白为什么globals.cpp中的const全局定义/初始化需要extern关键字? I tried removing the extern keywords in globals.cpp thinking that it wasn't needed, but my program won't run without them. 我尝试删除globals.cpp中的extern关键字,认为它不需要,但我的程序不会没有它们。 I thought extern was only used for forward declarations? 我以为extern只用于前言声明? Why are they needed for the const global definitions/initializations ? 为什么const全局定义/初始化需要它们? Has it something to do with the namespace they are defined in? 它与定义的命名空间有关吗?

It's meant to reduce code bloat when including constants in multiple files 这意味着在多个文件中包含常量时减少代码膨胀

I would suggest not to focus on this kind of optimizations unless it becomes really necessary, and rather choose the simplest design: define those constants directly in the header file and include that header file from all translation units (".cpp files") that need to access those constants. 我建议不要专注于这种优化,除非它变得非常必要,而是选择最简单的设计:直接在头文件中定义这些常量,并包含来自所有需要的翻译单元(“.cpp文件”)的头文件访问这些常量。 Since those objects are const , they will have internal linkage and the linker won't be screaming at you due to violations of the One Definition Rule. 由于这些对象是const ,因此它们将具有内部链接,并且由于违反了One Definition Rule,链接器不会尖叫。

I tried removing the extern keywords in globals.cpp thinking that it wasn't needed, but my program won't run without them 我尝试删除globals.cpp中的extern关键字,认为它不需要,但我的程序不会没有它们

That's because namespace-scope const objects with static storage duration (like your pi variable) have internal linkage unless you explicitly define them as extern . 这是因为具有静态存储持续时间的命名空间范围const对象(如pi变量)具有内部链接,除非您明确将它们定义为extern

I thought extern was only used for forward declarations? 我以为extern只用于前言声明?

extern is used to declare a variable that is defined in another translation unit (".cpp file"). extern用于声明在另一个转换单元(“.cpp文件”)中定义的变量。 If the object is const , the translation unit that defines it needs to explicitly mark it as extern in order for it to have external linkage and be visible from other translation units (this wouldn't be necessary if the object were not const ). 如果对象是const ,则定义它的转换单元需要将其明确标记为extern ,以使其具有外部链接并且可以从其他转换单元看到(如果对象不是const则不需const )。

Has it something to do with the namespace they are defined in? 它与定义的命名空间有关吗?

No, this is the rule for all namespace-level const objects with static storage duration, and it is specified in paragraph [basic.link]/3 of the C++ Standard: 不,这是具有静态存储持续时间的所有命名空间级别const对象的规则,并且在C ++标准的[basic.link] / 3段中指定:

A name having namespace scope (3.3.6) has internal linkage if it is the name of 具有命名空间作用域(3.3.6)的名称具有内部链接(如果它的名称)

(3.1) [...] — a variable, function or function template that is explicitly declared static; (3.1)[...] - 显式声明为静态的变量,函数或函数模板; or, 要么,

(3.2) — a variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage ; (3.2) - 非易失性const限定类型的变量,既未明确声明为extern,也未声明为具有外部链接 ; or 要么

(3.3) — a data member of an anonymous union. (3.3) - 匿名工会的数据成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM