多个文件中的常量定义

时间:2015-04-04 18:53:50

标签: c++ const

我正在阅读" C ++ primer plus"。在第9章中,它讨论了处理const修饰符时C ++和C之间的区别:

"在C ++(但不是C)中,const修饰符稍微改变了默认存储类。默认情况下,全局变量具有外部链接,而const全局变量默认具有内部链接。

...

如果全局const声明具有外部链接作为常规变量do,则这将是一个错误,因为您只能在一个文件中定义全局变量。也就是说,只有一个文件可以包含过程声明,其他文件必须使用extern关键字提供参考声明。"

我尝试使用以下程序测试此声明:

file.h:

using namespace std;

const char *constant = "Magic";

file1.cpp

#include <iostream>
#include "file.h"
extern void file2();
int main(){
  cout << "constant = " << constant << endl;
  file2();
}

file2.cpp

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

void file2(){
  cout << "file2 constant = " << constant << endl;
}

生成文件:

CFLAGS = -Wall -g
INCLUDE = file.h
src = file2.cpp file1.cpp

all: $(src) $(INCLUDE)
  g++ $(CFLAGS) -o file $(src)

clean:
  rm -f file

当我这样做时,我收到以下错误消息:

g++ -Wall -g -o file file2.cpp file1.cpp
/tmp/ccdl16Tw.o:(.data+0x0): multiple definition of `constant'
/tmp/ccA3ZEHa.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [all] Error 1

gcc版本4.8.2

更新:

如果我这样做

 char* const constant = "Magic";

然后make会给我这个警告:

g ++ -Wall -g -o file file2.cpp file1.cpp

In file included from file2.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";
                        ^
In file included from file1.cpp:2:0:
file.h:3:24: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char* const constant = "Magic";

1 个答案:

答案 0 :(得分:13)

const char *constant不是const。它是指向const的非const char指针。在命名空间范围内是非const变量,默认情况下它具有外部链接,因此您会得到多个定义错误。

const char * const constantconst,并且会按照您的预期行事。

更新

另一方面,

char* const constant是指向const的{​​{1}}指针。作为char,它在命名空间范围内默认具有内部链接。

但是,您不应该使用字符串文字初始化它(因为编译器警告指出),因为标准不允许这样做(这种转换在c ++ 11中是非法的,在此之前已被弃用)。允许将字符串文字存储在只读内存中,并且不允许您修改它们的运行时。这就是为什么指向带有非const指针的字符串文字是危险的。