2012-07-12 80 views
2

或者我有兩個文件,每個文件都有一個全局初始化。一個取決於另一個。跨C++翻譯單元初始化

簡化的例子:

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 

當我運行這個,它segfaults。 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() 

反正有沒有做什麼,我試圖做的(記住,這是一個過於簡單的例子)?或者,我是否受編譯器/鏈接器選擇的初始化順序的支配?

回答

5

您需要使前綴字符串在其他字符串之前。一種方法是將其更改爲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; 
} 

最後,只是一個提示:名稱與所有大寫字母僅用於大多數編碼約定宏,所以我會避免變量和函數這樣的名字。

0

這顯然不是一個便攜式解決方案,但對於gcc,您可以使用function attributes - 與__attribute__語法。即__init_priority__ (priority)屬性。初始化優先級跨越翻譯單元。 link