跨c++翻译单元初始化
Initialization across c++ translation units
或者我有两个文件,每个文件都有一个全局初始化。一个取决于另一个。
简化示例:
file1.h:
#include <string>
extern const std::string PREFIX;
file1.cpp:
#include "file1.h"
const std::string PREFIX = "prefix,";
file2.cpp:
#include "file1.h"
std::string MSG = PREFIX + "body";
int main(){}
我这样编译它们:
/usr/local/bin/g++-4.6.2 -c -Wall -g -o file1.o file1.cpp
/usr/local/bin/g++-4.6.2 -c -Wall -g -o file2.o file2.cpp
/usr/local/bin/g++-4.6.2 -Wall -g -o example file1.o file2.o
当我运行这个时,它会出错。gdb跟踪:
Starting program: example
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b7ae0b in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) ()
from /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/libstdc++.so.6
(gdb) bt
#0 0x00007ffff7b7ae0b in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) ()
from /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/libstdc++.so.6
#1 0x00000000004009b5 in std::operator+<char, std::char_traits<char>, std::allocator<char> > (__lhs=Traceback (most recent call last):
File "/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../share/gcc-4.6.2/python/libstdcxx/v6/printers.py", line 587, in to_string
return ptr.lazy_string (length = len)
RuntimeError: Cannot access memory at address 0xffffffffffffffe8
, __rhs=0x400af0 "body") at /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/include/c++/bits/basic_string.h:2346
#2 0x000000000040095f in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at file2.cpp:3
#3 0x000000000040098b in _GLOBAL__sub_I_MSG () at file2.cpp:6
#4 0x0000000000400ab6 in __do_global_ctors_aux ()
#5 0x00000000004006e3 in _init ()
#6 0x00007ffff7ffa5a0 in ?? ()
#7 0x0000000000400a45 in __libc_csu_init ()
#8 0x00007ffff72dcbe0 in __libc_start_main () from /lib/libc.so.6
#9 0x00000000004007c9 in _start ()
有没有什么可以做我想做的事情(记住这是一个过于简化的例子)?还是我受编译器/链接器选择的初始化顺序的支配?
您需要使前缀字符串位于其他字符串之前。一种方法是将其更改为C字符串
// header
#include <string>
extern const char * const PREFIX;
// .cpp file
const char * const PREFIX = "prefix,";
另一种方法是从函数返回前缀,并在以前使用PREFIX
的地方使用PREFIX()
。
// header
inline const string& PREFIX() {
static const string value = "prefix,";
return value;
}
最后,只是一个提示:只有在大多数编码约定中,所有大写字母的名称才用于宏,所以我会避免为变量和函数使用这样的名称。
我想这是因为代码试图以错误的顺序初始化全局变量。有一个关于初始化顺序的SO问题,它的答案应该是有用的。
这显然不是一个可移植的解决方案,但对于gcc,您可以使用函数属性-使用__attribute__
语法。即__init_priority__ (priority)
属性。初始化优先级跨翻译单元。链接
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- 静态变量在同一个翻译单元中被静态方法使用时是否保证被初始化?
- 使用全局变量初始化不同编译单元中的其他全局变量
- MSVC 2017 在单个翻译单元中违反静态初始化顺序
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 尝试使用 uint*& 作为常量单元*&失败:从类型"uint8_t"的表达式初始化类型"const uint8_t*&"的引用无效
- 在单元测试中初始化unique_ptr
- 跨c++翻译单元初始化
- c++变量/实例初始化跨不同翻译单元的顺序
- 一个编译单元中的静态初始化
- 不同翻译单元的变量初始化
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的
- 静态初始化顺序失败:相同的编译单元
- C++DoublyLinkedList单元测试通过智能初始化失败,但通过new初始化成功
- 动态初始化-跨翻译单元