c++ - 警告:“<匿名>”在此函数中未初始化 [-Wuninitialized]
问题描述
以下程序编译时没有警告-O0
:
#include <iostream>
struct Foo
{
int const& x_;
inline operator bool() const { return true; }
Foo(int const& x):x_{x} { }
Foo(Foo const&) = delete;
Foo& operator=(Foo const&) = delete;
};
int main()
{
if (Foo const& foo = Foo(3))
std::cout << foo.x_ << std::endl;
return 0;
}
但是,使用-O1
或更高时,它会发出警告:
maybe-uninitialized.cpp: In function ‘int main()’:
maybe-uninitialized.cpp:15:22: warning: ‘<anonymous>’ is used uninitialized in this function [-Wuninitialized]
std::cout << foo.x_ << std::endl;
你如何摆脱这个警告-O1
和更高?
这样做的动机是CHECK(x)
宏必须捕获一个常量引用而不是一个值,以免触发析构函数、复制构造函数等以及打印出一个值。
分辨率在底部
编辑:
$ g++ --version
g++ (GCC) 8.2.1 20181127
No warnings: g++ maybe-uninitialized.cpp -Wall -O0
With warning: g++ maybe-uninitialized.cpp -Wall -O1
编辑 2 以回应@Brian
#include <iostream>
struct CheckEq
{
int const& x_;
int const& y_;
bool const result_;
inline operator bool() const { return !result_; }
CheckEq(int const& x, int const &y):x_{x},y_{y},result_{x_ == y_} { }
CheckEq(CheckEq const&) = delete;
CheckEq& operator=(CheckEq const&) = delete;
};
#define CHECK_EQ(x, y) if (CheckEq const& check_eq = CheckEq(x,y)) \
std::cout << #x << " != " << #y \
<< " (" << check_eq.x_ << " != " << check_eq.y_ << ") "
int main()
{
CHECK_EQ(3,4) << '\n';
return 0;
}
上面更有趣的是没有警告,但输出取决于-O0
or -O1
:
g++ maybe-uninitialized.cpp -O0 ; ./a.out
Output: 3 != 4 (3 != 4)
g++ maybe-uninitialized.cpp -O1 ; ./a.out
Output: 3 != 4 (0 != 0)
编辑 3 - 接受的答案
感谢@RyanHaining。
#include <iostream>
struct CheckEq
{
int const& x_;
int const& y_;
explicit operator bool() const { return !(x_ == y_); }
};
int f() {
std::cout << "f() called." << std::endl;
return 3;
}
int g() {
std::cout << "g() called." << std::endl;
return 4;
}
#define CHECK_EQ(x, y) if (CheckEq const& check_eq = CheckEq{(x),(y)}) \
std::cout << #x << " != " << #y \
<< " (" << check_eq.x_ << " != " << check_eq.y_ << ") "
int main() {
CHECK_EQ(f(),g()) << '\n';
}
输出:
f() called.
g() called.
f() != g() (3 != 4)
特征:
- 每个参数
CHECK_EQ
只检查一次。 - 输出显示内联代码比较以及值。
解决方案
该代码具有未定义的行为。调用Foo
的构造函数会导致prvalue3
作为一个临时对象具体化,该对象绑定到参数x
。但是,该临时对象的生命周期在构造函数退出时结束,并在评估x_
时作为悬空引用留下。foo.x_
您需要提供有关您希望CHECK
宏如何工作的更多详细信息,然后才能建议一种实现它的方法,而无需执行您在此处所做的事情。
推荐阅读
- angular - 类型 '{ label: string; 上不存在属性 'description' 值:字符串;}'
- python - sqlite SELECT 语句返回无
- c - C语言中的无穷正弦生成
- azure-api-management - Azure APIM 策略使用访问密钥对应用配置服务进行身份验证
- java - 掉落物品龙头
- arrays - 短路评估混乱
- python - 如何在 R 中创建三元热图?
- python - Python - 根据数据框中的信息创建包含团队对手名称的列
- php - Laravel Jetstream 和 AWS SES 更改发件人电子邮件地址
- python - 在熊猫中按十一个多列分组