抱歉,是否曾经有人问过。我搜索了互联网,但没有找到答案。
说我有一个文件Common.h
,A.cpp
并B.cpp
包含Common.h
。
如果我想有一个全球性const char *
的Common
翻译单元,我必须说extern
的Common.h
,并在定义它Common.cpp
。否则,如果仅const char * MSG = "Hello World";
在中定义,则在编译期间Common.h
会出现duplicate symbol
错误。
但是,如果我仅Common.h
使用如下语句定义全局const int,const int CONSTANT = 10;
则代码将编译而不会出现重复的符号错误,并且一切正常。
我对为什么会这样感到困惑。在我看来,上面两个示例之间的唯一区别是类型,我认为这没有什么区别。为什么我得到C字符串的重复符号错误,而不是整数?
假设main.cpp
,A.h
,B.h
,A.cpp
,和B.cpp
看起来像下面这样:
// A.h
#pragma once
void f();
// A.cpp
#include "A.h"
#include "Common.h"
#include <iostream>
void f() {
std::cout << MSG << std::endl;
}
// B.h
#pragma once
void g();
// B.cpp
#include "B.h"
#include "Common.h"
#include <iostream>
void g() {
std::cout << CONSTANT << std::endl;
}
// main.cpp
#include "A.h"
#include "B.h"
int main()
{
f();
g();
}
现在,假设我们使用command进行编译g++ main.cpp A.cpp B.cpp Common.cpp -std=c++14
。
如果我们做Common.h
与Common.cpp
以下内容,然后编译失败,错误duplicate symbol MSG
:
// Common.h
#pragma once
const char * MSG = "Hello World";
const int CONSTANT = 10; // defined in header file
// Common.cpp
// empty
但是,这将编译:
// Common.h
#pragma once
extern const char * MSG;
const int CONSTANT = 10; // defined in header file
// Common.cpp
#include "Common.h"
const char * MSG = "Hello World";
我想知道为什么我们需要extern并将字符串的定义和声明分开,而不是int。
有人建议将C字符串类型const char * const
改为const char *
。为什么使指针const起作用?另外,在这种情况下,此解决方案与我上面提供的解决方案(在此我们将字符串改为extern并拆分定义/声明)之间有什么区别?为什么这两种方法都能解决编译错误,并且两种方法之间有什么区别?
我还注意到,如果我const int
变成just int
,那么我会duplicate symbol
再次得到错误。我觉得这背后的原因与上述问题的答案有关。为什么会这样呢?
这是C和C ++的差异之一。
在C ++中,const
变量是隐式的static
,即仅对当前翻译单元可见。在C中,它extern
对于整个程序是隐式可见的(这也是C和C ++中其他非const声明的默认值)。
这解释了您的观察。
注意:const char *p
变量的声明不是const
变量。这意味着它指向一个const变量(即*p
无法修改),但p
其本身不是const
。因此,这里的行为是不同的。const char * const p
将是一个const声明。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句