编译器构造 - 常量引用在C++中是否具有外部链接
compiler construction - Does const reference have external linkage in C++?
根据 1998 年标准第 3.5 节第 3 C++条,常量引用具有内部链接。
具有命名空间范围 (3.3.5) 的名称具有内部链接,如果它是
- 明确声明
显式声明为 static 的对象、引用、函数或函数模板,或者,
为const的对象或引用,既未明确声明extern,也未先前声明具有外部链接;或
匿名工会的数据成员。
但是为什么在编译下面的代码时会产生多个定义冲突呢?
// a.cpp
const int& a = 1;
int main()
{
return 0;
}
// b.cpp
const int& a = 1;
然后编译代码。
$ g++ a.cpp b.cpp
/tmp/ccb5Qi0M.o:(.bss+0x0): multiple definition of `a'
/tmp/ccD9vrzP.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
如果将 const 引用更改为 const,如下所示
// a.cpp
const int a = 1;
int main()
{
return 0;
}
// b.cpp
const int a = 1;
编译是可以的。
引用本身不是const
,只是它引用的对象; 所以(可以说)这个规则没有给引用内部链接。
引用声明为const
是没有意义的。C++11标准澄清了措辞:
显式声明
const
或constexpr
且既未显式声明extern
也未声明为具有外部链接的变量
没有提到const
声明的引用的荒谬概念.
我认为@Mike是正确的,这里没有新东西,只是一点提示。
有引用和引用的对象,对象可以是常量然后是内部链接,但引用本身永远不可能是常量,因为它没有 CV 概念(引用在声明期间初始化,然后永远不要转移到其他对象,我记得 GCC 抱怨如果你给出一个常量引用,意思是 int const&r = o; 虽然 VS 没有抱怨, 这毫无意义),因为引用既不是常量也不是静态的,那么声明会交叉源文件。
这是一个具有有史以来最常量引用的程序。它编译并与C++17链接(尝试一下):
// a.cpp
extern const int& ir;
int main() { return ir; }
// b.cpp
constexpr const int& ir = 42;
如您所见,ir
可以从另一个翻译单元引用,即它具有外部链接。
结论:全局引用变量具有外部链接,除非声明为 static
或在匿名命名空间中。此外,引用上的constexpr
关键字不会使引用成为引用对象的常量视图(尝试一下)。
并且constexpr
引用不是隐式inline
.这是对 C++17 中ir
的重新定义(试试看):
// a.cpp
constexpr const int& ir = 42;
int main() { return ir; }
// b.cpp
constexpr const int& ir = 42;
如果在两个文件中将inline
放在ir
声明之前,它将编译并链接(尝试一下)。
- 有了gcc,是否可以链接库,但前提是它存在
- Windows 链接器是否使用 LoadLibrary 解析 DLL 中未定义的符号?
- 如果包含映射的静态库与可执行文件和动态库链接,静态映射(变量)是否会被多次释放?
- 是否可以在调用链接器时强制 CMake 重新排序参数?
- C++标准是否定义了结构中成员函数的函数内定义是否必须具有静态链接?
- lambda 的调用运算符是否需要具有链接?
- 是否应该链接带有实现的头文件?
- 我的 RichEdit 控件是否可以包含可单击的链接?
- 在这种情况下,GCC 和 clang 是否显示与 Visual Studio 相同的结果,关于语言链接?
- 在线C++标准草案的更新是否会使指向它的链接无效?
- 在链接的程序集文件中,我想从 c++ 调用代码访问变量.是否可以在不触发访问冲突的情况下执行此操作?
- 内联是否决定内部链接?
- 是否可以将同一组源数据与不同的表模型链接起来?
- 当用作模板参数时,功能指针是否需要指向具有外部链接的函数
- 链接时,"grab what you need" 和 "grab all" 之间是否有某些内容(-wl,--whole-archive)?
- boost::instrusive::list 带有自动取消链接钩子:我可以使用列表中的值来确定列表是否只有一个元素
- 是否有 gcc 命令可以链接同一目录中的所有 .o 文件并生成.exe文件
- 链接 gcc 6、gcc 7 和 gcc 8 对象是否安全?
- g++是否将C标准库的名称声明为外部"C"链接或外部"C++"?
- 是否链接已构建的静态库而不是使用add_subdirectory