提问人:Juliean 提问时间:11/5/2021 最后编辑:Juliean 更新时间:11/9/2021 访问量:179
保持对局部变量的常量引用是 UB 吗?
Is it UB to keep a const-reference to a local variable?
问:
在编译启用代码优化(准确地说是 MSVC)时,我遇到了多个问题。实际情况是大型代码库的一部分,需要复杂的设置才能复制,但本质上可以归结为以下结构:
struct VariableView
{
const void* pValue;
};
template<typename Type>
[[nodiscard]] VariableView createView(const Type& value)
{
return {&value};
}
void serializeStruct(Struct value)
{
const auto view = createView(value);
serializeGeneric(view);
}
我遇到的错误围绕着“value”的内容在调用“createView”之后被覆盖,但在调用“serializeGeneric”之前/之前。这是我通过调试和查看生成的程序集所能知道的,所以我假设编译器以某种方式(错误地)假设变量“value”在调用 createView 后不再使用,因此决定将下一个必需的值重新分配给其原始本地值。
但是,在我向 MSVC 编译器提交错误报告之前,我想确保:由于标准,我在这里所做的实际上应该是有效的 C++,还是我通过将局部变量的地址存储在“VariableView”结构中来遇到 UB 我正在做的方式?
编辑:好的,所以我已经能够把问题归结为问题。编译器的混淆似乎来自这样一个事实,即实际代码中的类型是由模板推导出来的。这是重现该问题的完整代码:
https://www.paste.org/120337(对不起,编辑一直说我的代码格式不正确,所以我不得不使用外部网站)。
在带有 /O2 的 MSVC 中,accessData 中“临时”结构的前两个变量将损坏(O1 或更低可解决问题。按值传递string_view似乎是导致值被覆盖的原因。 如果我将参数列表中的类型特征替换为它们的简单定义,即使该特征解析为完全相同的基础类型,该错误实际上也会消失。所以,如果你认为这里还有其他可疑的东西,请告诉我,但我也会提交一份错误报告,因为我现在非常确定它是不对的(而且我现在有一个最小的例子)。
编辑2:我的报告已提交(https://developercommunity.visualstudio.com/t/Type-trait-as-argument-type-leads-to-opt/1572875)并且已经在调查中。
答: 暂无答案
评论
value
view.pValue
value
AccessData
value