我检查了 /usr/include/c++/4.6/bits/ios_base.h 中 std::ios::app 的定义,发现 std::ios::app 被定义为 const 静态变量:
typedef _Ios_Openmode openmode;
/// Seek to end before each write.
static const openmode app = _S_app;
其中 _Ios_Openmode 在同一个头文件中定义为
enum _Ios_Openmode
{
_S_app = 1L << 0,
_S_ate = 1L << 1,
_S_bin = 1L << 2,
_S_in = 1L << 3,
_S_out = 1L << 4,
_S_trunc = 1L << 5,
_S_ios_openmode_end = 1L << 16
};
众所周知,静态变量具有内部链接,每个翻译单元都有自己的静态变量副本,这意味着不同翻译单元中的静态变量应该有不同的地址。但是,我使用了两个单独的程序来打印 std::ios::app 的地址,发现打印的地址是一样的:
源文件 test1.cpp
#include <iostream>
int main() {
std::cout << "address: " << &std::ios::app << std::endl;
return 0;
}
结果
address: 0x804a0cc
源文件 test2.cpp 与 test1.cpp 相同,结果相同:
address: 0x804a0cc
这真的让我很困惑,不同翻译单元中的静态变量不应该有不同的地址吗?
更新:正如评论中指出的那样, std::ios::app 是一个静态数据成员,而不是一个静态 const 变量;静态数据成员有外部链接,不同翻译单元的静态数据成员地址应该相同。第二点是我验证这个事实的方法是错误的:不同的程序并不意味着不同的翻译单元。