我在共享库中使用了RapidJSON,从某个时候开始定义这样的方法:
template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
static const char escape[256] = {
Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
};
#undef Z16
//!@endcond
我不明白的是为什么这会导致重定位:
readelf的输出:
823: 0000000000051b00 256 OBJECT UNIQUE DEFAULT 14 _ZZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE19ParseStringToStreamILj0ES2_S2_9PhpStreamNS4_11StackStreamIcEEEEvRT2_RT3_E6escape
如果变量不是外部变量,为什么将符号与STB_GNU_UNIQUE绑定?不仅仅是指令指针的静态偏移就足以获取此数据?
答案 0 :(得分:1)
函数似乎已被内联,因为已显式请求内联,但是在编译器内联指令时,它决定仅发出e:\Work\Dev\StackOverflow\q052302083>test.exe
Enter n (invalid, to exit): 6
Results for 6 (with a step of: 2):
6 4 2 4 6
Enter n (invalid, to exit): 7
Results for 7 (with a step of: 2):
7 5 3 1 3 5 7
Enter n (invalid, to exit): 8
Results for 8 (with a step of: 2):
8 6 4 2 4 6 8
Enter n (invalid, to exit): 9
Results for 9 (with a step of: 2):
9 7 5 3 1 3 5 7 9
Enter n (invalid, to exit): 3
Results for 3 (with a step of: 2):
3 1 3
Enter n (invalid, to exit): 2
Results for 2 (with a step of: 2):
2
Enter n (invalid, to exit): 1
Results for 1 (with a step of: 2):
1
Enter n (invalid, to exit): q
数组的一个副本,链接器将合并该数组的一个副本跨翻译单元,因此整个程序中只有一个副本,因此编译器需要发出一个符号,以便该函数的每个内联副本都可以找到escape
。
(注意:从技术上讲,标准要求在带有外部链接的内联函数的主体中声明的escape
局部变量具有唯一的地址。但是,我查看了源代码,看来{{ 1}}未被使用,因此这个唯一的地址是不可观察的;编译器可以选择将该数组的内容内联到每个转换单元中,但是,每个转换单元浪费了256个字节。)