gpt4 book ai didi

c++ - Volatile 关键字允许访问 UnitTest++ 中的常量结构

转载 作者:搜寻专家 更新时间:2023-10-31 01:16:27 25 4
gpt4 key购买 nike

我正在使用 UnitTest++ 框架对我负责的一些 C 代码实现单元测试。最终产品是嵌入式的,并使用 const 结构来保存配置信息。由于目标主机可以异步修改配置,因此结构的成员都是易变的。一些结构也被声明为易变的。

当我使用 const_cast 尝试修改 UnitTest Windows 7 主机上缺少 volatile 关键字的结构实例时,我遇到了段错误。这对我来说很有意义。但是,如果使用 volatile 关键字声明结构实例,则测试通过。这对我来说没有意义。

这是一个快速代码示例,它显示了 Win7 上 gcc 的问题。切换定义值会导致出现或不出现段错误,具体取决于是否使用了结构的可变实例。

typedef struct
{
volatile int foo;
volatile int bar;
} TestStruct;

const TestStruct constStruct = { 1, 2};
volatile const TestStruct volatileConstStruct = { 3, 4};

#define SEG_FAULT 0

int main(void)
{
TestStruct * constPtr = const_cast<TestStruct*>(&constStruct);
TestStruct * constVolPtr = const_cast<TestStruct*>(&volatileConstStruct);

#if(SEG_FAULT == 0)
constVolPtr->foo = 10;
#else
constPtr->foo = 20;
#endif
}

任何人都可以帮助我理解为什么 volatile 关键字提供了段错误的解决方法吗?另外,任何人都可以建议一种方法来允许我修改结构中的值以进行单元测试,而无需将 volatile 关键字添加到所有结构实例吗?

编辑:

我刚刚发现您可以在 C 中执行此操作:

#define const

在测试夹具中包含上面有效的“const undefine”允许我的目标编译器看到 const 关键字并将结构正确地放入闪存中。但是,UnitTest++ 编译器上的预处理器删除了 const 关键字,因此我的测试夹具能够修改结构。

此解决方案的缺点是我无法添加单元测试来验证函数调用的 const 操作是否正确。但是,由于从结构实例中删除 const 不是一个选项(需要将数据放在闪存中),这似乎是一个我将不得不忍受的缺点。

最佳答案

为什么会出现这种奇怪的行为?
使用 const_cast 修改 const 对象是一种未定义行为
const_cast 当你有一个指向非 const 对象的 const 指针并且你想将你的指针指向它时使用。

为什么它适用于 volatile
没有把握。然而,它仍然是一个未定义的行为,你很幸运它能工作。

Undefined Behavior 的问题是所有安全赌注都已关闭,程序可能会显示任何行为。它可能看起来有效,也可能无效。可能会崩溃或显示任何奇怪的行为。
最好不要编写任何表现出未定义行为的代码,这样可以节省对此类情况的保证解释。

如何解决?
不要将你修改的对象声明为const,因为你打算在你的程序/测试过程中修改它们,所以它们不应该是const。目前,您向编译器 promise 您的结构对象是不可变的(const),但后来您通过修改它来破坏该契约(Contract)。只有在你能遵守的情况下才能做出这个 promise 。

关于c++ - Volatile 关键字允许访问 UnitTest++ 中的常量结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9085627/

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