多个文件中的常量定义
Constant definition in multiple files
我正在阅读"C++ primer plus"。第九章讲了C++和C在处理const修饰符时的区别:
"在 C++(但不是 C)中,const 修饰符稍微改变了默认存储 类。虽然全局变量默认具有外部链接,但 const 全局变量默认具有内部链接。
...
如果全局 const 声明像常规变量一样具有外部链接,这将是一个错误,因为您只能在一个文件中定义一个全局变量。也就是说,只有一个文件可以包含过程声明,其他文件必须使用 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 文件 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";
const char *constant
不是 const
。它是一个指向 const char
的非 const
指针。作为命名空间范围内的非 const
变量,它默认具有外部链接,因此会出现多重定义错误。
const char * const constant
是 const
并且会按照您的预期运行。
更新:
另一方面,char* const constant
将是指向 char
的 const
指针。作为 const
它在命名空间范围内默认具有内部链接。
但是,您不应使用字符串文字对其进行初始化(如编译器警告所指出的那样),因为标准不允许这样做(这种转换在 c++11 中是非法的,并且在此之前已被弃用)。允许将字符串文字存储在只读内存中,并且不允许您在运行时修改它们。这就是为什么使用指向非 const char
的指针指向字符串文字是危险的。
我正在阅读"C++ primer plus"。第九章讲了C++和C在处理const修饰符时的区别:
"在 C++(但不是 C)中,const 修饰符稍微改变了默认存储 类。虽然全局变量默认具有外部链接,但 const 全局变量默认具有内部链接。
...
如果全局 const 声明像常规变量一样具有外部链接,这将是一个错误,因为您只能在一个文件中定义一个全局变量。也就是说,只有一个文件可以包含过程声明,其他文件必须使用 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 文件 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";
const char *constant
不是 const
。它是一个指向 const char
的非 const
指针。作为命名空间范围内的非 const
变量,它默认具有外部链接,因此会出现多重定义错误。
const char * const constant
是 const
并且会按照您的预期运行。
更新:
另一方面,char* const constant
将是指向 char
的 const
指针。作为 const
它在命名空间范围内默认具有内部链接。
但是,您不应使用字符串文字对其进行初始化(如编译器警告所指出的那样),因为标准不允许这样做(这种转换在 c++11 中是非法的,并且在此之前已被弃用)。允许将字符串文字存储在只读内存中,并且不允许您在运行时修改它们。这就是为什么使用指向非 const char
的指针指向字符串文字是危险的。