编译单元之间共享的全局常量对象 [英] Global const object shared between compilation units

查看:129
本文介绍了编译单元之间共享的全局常量对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  // ConstClass.h 
类ConstClass $ b $当我声明并初始化一个const对象时。 b {
};

const ConstClass g_Const;

两个cpp文件包含这个头文件。



< pre $ // Unit1.cpp
#includeConstClass.h
#includestdio.h

void PrintInUnit1()
{
printf(单元1中的g_Const为%d.\r \ n,& g_Const);
}



<$ p

$ void PrintInUnit2()
{
printf(单元2中的g_Const是%d.\r\\\
,& g_Const);
}

当我构建解决方案时,没有链接错误,您会得到如果g_Const是非常量基本类型!

PrintInUnit1()和PrintInUnit2()显示在两个编译单元中有两个独立的具有不同地址的g_Const ,为什么?



==============



我知道如何(使用extern关键字声明,并将其定义在一个cpp文件中。)



我想知道为什么我没有在此处找到重定义链接错误样本。 解决方案

https:/ /stackoverflow.com/a/6173889/1508519


名称空间范围内的const变量具有内部链接。所以他们基本上是两个不同的变量。没有重新定义。



3.5 / 3 [basic.link]:
$ b

名称空间范围3.3.5)如果它是
的名称,则具有内部链接



- 显式声明
的对象,引用,函数或函数模板静态或者,

- 明确声明为const的对象或引用,既不明确声明为extern也不声明具有外部
链接的
;或

- 匿名工会的数据成员。


使用 extern 如果您希望它有外部链接。






在另一个答案中指出,头文件只是粘贴在cpp文件中。两个cpp文件都包含相同的头文件,但它们是独立的翻译单元。这意味着变量的一个实例与另一个实例不同。在其他语言中,让编译器知道你已经在其他地方定义了变量,使用 extern 关键字。这确保只有一个实例在翻译单元之间共享。但是 extern const Test test 只是一个声明。你需要一个定义。只要在某个cpp文件中定义了一次,就无关紧要。你可以根据需要多次声明它(这很方便将它放在头文件中)。



例如:



Constant.h

  class Test 
{
};

extern const测试测试;

Unit1.cpp

  #includeConstant.h
#include< iostream>

void print_one()
{std :: cout<< & test<<的std :: ENDL; }

Unit2.cpp

  #includeConstant.h
#include< iostream>

void print_two()
{std :: cout<< & test<<的std :: ENDL; }

main.cpp

  extern void print_one(); 
extern void print_two();

int main()
{
print_one();
print_two();

$ / code>

Constant.cpp

  #includeConstant.h
const Test test = Test();

Makefile

  .PHONY:all 
all:
g ++ -std = c ++ 11 -o test Constant.cpp Unit1.cpp Unit2.cpp main.cpp


When I declared and initialized a const object.

// ConstClass.h
class ConstClass
{
};

const ConstClass g_Const;

And two cpp files include this header.

// Unit1.cpp
#include "ConstClass.h"
#include "stdio.h"

void PrintInUnit1( )
{
    printf( "g_Const in Unit1 is %d.\r\n", &g_Const );
}

and

// Unit2.cpp
#include "ConstClass.h"
#include "stdio.h"

void PrintInUnit2( )
{
    printf( "g_Const in Unit2 is %d.\r\n", &g_Const );
}

When i build the solution, there was no link error, what you will get If g_Const is a non-const fundamental type!

And PrintInUnit1() and PrintInUnit2() show that there are two independent "g_Const"s with different address in two compilation units, Why?

==============

I know how to fix it.(use extern keyword to declaration, and define it in one cpp file.)

I wonder to know why I did't get redfined link error in this sample.

解决方案

https://stackoverflow.com/a/6173889/1508519

const variable at namespace scope has internal linkage. So they're basically two different variables. There is no redefinition.

3.5/3 [basic.link]:

A name having namespace scope (3.3.5) has internal linkage if it is the name of

— an object, reference, function or function template that is explicitly declared static or,

— an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or

— a data member of an anonymous union.

Use extern if you want it to have external linkage.


As stated in the other answer, header files are just pasted in cpp files. The same header file is included in both cpp files, but they are separate translation units. That means that one instance of a variable is different from the other instance. In other to let the compiler know that you have defined the variable elsewhere, use the extern keyword. This ensures only one instance is shared across translation units. However extern const Test test is just a declaration. You need a definition. It doesn't matter where you define it as long as it is defined once in some cpp file. You can declare it as many times as you want (which is convenient for placing it in a header file.)

So for example:

Constant.h

class Test
{
};

extern const Test test;

Unit1.cpp

#include "Constant.h"
#include <iostream>

void print_one()
{ std::cout << &test << std::endl; }

Unit2.cpp

#include "Constant.h"
#include <iostream>

void print_two()
{ std::cout << &test << std::endl; }

main.cpp

extern void print_one();
extern void print_two();

int main()
{
   print_one();
   print_two();
}

Constant.cpp

#include "Constant.h"
const Test test = Test();

Makefile

.PHONY: all
all:
   g++ -std=c++11 -o test Constant.cpp Unit1.cpp Unit2.cpp main.cpp

这篇关于编译单元之间共享的全局常量对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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