gpt4 book ai didi

c++ - 一条定义规则警告

转载 作者:可可西里 更新时间:2023-11-01 18:19:48 26 4
gpt4 key购买 nike

我被严重的“单一定义规则”违规所困扰。我现在害怕在我的项目中有很多细微的错误。

例如,以下程序将导致在 visual studio 2015 中取消引用空指针:

Source1.cpp:
----------
struct S {
double d = 0;
};

void Foo() {
S s;
}


Source2.cpp:
-----------
struct S {
int a = 0;
};

int main() {

int value = 5;
int& valueRef = value;
S s; // valueRef is erased due to S::d initialization from Source1.cpp

valueRef++; // crash
}

编译时没有警告。

这很糟糕,因为 Source2.cpp 甚至没有使用 Source1.cpp 中的任何内容。如果我从项目中删除 Source1.cpp,它仍然可以编译,并且不再有问题。

在大型项目中,似乎很难确保没有任何 cpp 文件“本地”定义具有已定义名称的结构或类。

我有一些类,例如 PointSerieStateItem,...我虽然这在小型 cpp 文件中没问题,但我意识到这不安全。

是否有编译器警告来捕获此类错误?如果不是,避免违反 ODR 的最佳做法是什么?

最佳答案

在这种特殊情况下,最底层的 ODR 违规(实际上导致您正在观察的问题)是类 S 的隐式定义的 inline 构造函数.您的程序有两个不匹配版本的内联 S::S() 函数,这可以被视为由原始 ODR 违规(即同一类定义不同)引起的另一个 ODR 违规。

实现很难在当前的 C++ 编译基础结构方法中“看到”这个错误。当然,付出足够的努力也是可以的。

在这种情况下,为了使错误“可见”,您可以显式声明类构造函数并将其定义为具有空主体的非内联函数。两个非内联 S::S() 的存在将触发链接器错误。

可以理解,您可能会认为这是一种过于人为的措施,在某些情况下是 Not Acceptable ,因为它可能会改变类的“聚合”状态。

关于c++ - 一条定义规则警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40659435/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com