静态结构和一个定义规则
Static struct and One Definition Rule
1.cpp:
static struct SA {
int m=1;
int func() {return m;}
}g;
static void test() {
g.func();
}
2.cpp:
static struct SA {
int m=2;
int func() {return m*m;}
}g;
static void test() {
g.func();
}
(1) 这种情况是否违反了一个定义规则?
(2) 如果不是,那么只有在某处引用 SA 时才会违反 ODR?
是的,违反了规则。比如说,如果两个 .cpp 都构建在同一个静态库中并且使用了其中一个,那么它会导致 UB。这是因为 linker 不能相当随机地分辨两者和 links 之间的区别。当您 link 多个定义相同符号的静态库时,也会发生同样的情况。链接器只是假设它们是相同的。
事实上,由于 headers.
中的 functions/class 定义,link 用户经常不得不丢弃重复项
IIRC 共享库/.dll 对这个问题更有弹性,因为只有非常有限的符号暴露给 linker。
在 C++20 中,模块应该可以解决此类问题。
1.cpp:
static struct SA {
int m=1;
int func() {return m;}
}g;
static void test() {
g.func();
}
2.cpp:
static struct SA {
int m=2;
int func() {return m*m;}
}g;
static void test() {
g.func();
}
(1) 这种情况是否违反了一个定义规则? (2) 如果不是,那么只有在某处引用 SA 时才会违反 ODR?
是的,违反了规则。比如说,如果两个 .cpp 都构建在同一个静态库中并且使用了其中一个,那么它会导致 UB。这是因为 linker 不能相当随机地分辨两者和 links 之间的区别。当您 link 多个定义相同符号的静态库时,也会发生同样的情况。链接器只是假设它们是相同的。
事实上,由于 headers.
中的 functions/class 定义,link 用户经常不得不丢弃重复项IIRC 共享库/.dll 对这个问题更有弹性,因为只有非常有限的符号暴露给 linker。
在 C++20 中,模块应该可以解决此类问题。