以下程序编译时不会出现警告-O0:
#include <iostream>\n\nstruct Foo\n{\n int const& x_;\n inline operator bool() const { return true; }\n Foo(int const& x):x_{x} { }\n Foo(Foo const&) = delete;\n Foo& operator=(Foo const&) = delete;\n};\n\nint main()\n{\n if (Foo const& foo = Foo(3))\n std::cout << foo.x_ << std::endl;\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n但是,使用-O1或更高版本会发出警告:
maybe-uninitialized.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\nmaybe-uninitialized.cpp:15:22: warning: \xe2\x80\x98<anonymous>\xe2\x80\x99 is used uninitialized in this function [-Wuninitialized]\n std::cout << foo.x_ << std::endl;\nRun Code Online (Sandbox Code Playgroud)\n\n如何摆脱这个警告-O1?
这样做的动机是CHECK(x)宏必须捕获 const 引用而不是值,以免触发析构函数、复制构造函数等以及打印出值。
分辨率在底部
\n\n编辑:
\n\n$ g++ --version\ng++ (GCC) 8.2.1 20181127\n\nNo warnings: g++ maybe-uninitialized.cpp -Wall -O0\nWith warning: g++ maybe-uninitialized.cpp -Wall -O1\nRun Code Online (Sandbox Code Playgroud)\n\n编辑 2 回应@Brian
\n\n#include <iostream>\n\nstruct CheckEq\n{\n int const& x_;\n int const& y_;\n bool const result_;\n inline operator bool() const { return !result_; }\n CheckEq(int const& x, int const &y):x_{x},y_{y},result_{x_ == y_} { }\n CheckEq(CheckEq const&) = delete;\n CheckEq& operator=(CheckEq const&) = delete;\n};\n\n#define CHECK_EQ(x, y) if (CheckEq const& check_eq = CheckEq(x,y)) \\\n std::cout << #x << " != " << #y \\\n << " (" << check_eq.x_ << " != " << check_eq.y_ << ") "\n\nint main()\n{\n CHECK_EQ(3,4) << \'\\n\';\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n上面的内容更有趣,因为没有警告,但不同的输出取决于-O0或-O1:
g++ maybe-uninitialized.cpp -O0 ; ./a.out\nOutput: 3 != 4 (3 != 4) \n\ng++ maybe-uninitialized.cpp -O1 ; ./a.out\nOutput: 3 != 4 (0 != 0) \nRun Code Online (Sandbox Code Playgroud)\n\n感谢@RyanHaining。
\n\n#include <iostream>\n\nstruct CheckEq\n{\n int const& x_;\n int const& y_;\n explicit operator bool() const { return !(x_ == y_); }\n};\n\nint f() {\n std::cout << "f() called." << std::endl;\n return 3;\n}\n\nint g() {\n std::cout << "g() called." << std::endl;\n return 4;\n}\n\n#define CHECK_EQ(x, y) if (CheckEq const& check_eq = CheckEq{(x),(y)}) \\\n std::cout << #x << " != " << #y \\\n << " (" << check_eq.x_ << " != " << check_eq.y_ << ") "\n\nint main() {\n CHECK_EQ(f(),g()) << \'\\n\';\n}\nRun Code Online (Sandbox Code Playgroud)\n\n输出:
\n\nf() called.\ng() called.\nf() != g() (3 != 4) \nRun Code Online (Sandbox Code Playgroud)\n\n特征:
\n\nCHECK_EQ只检查一次。虽然具有用户定义构造函数的类无法延长临时构造函数的生命周期,但聚合可以。通过转换为聚合,我可以使你的方法发挥作用
#include <iostream>
struct CheckEq
{
int const& x_;
int const& y_;
bool const result_;
explicit operator bool() const { return !result_; }
};
// adding () here for macro safety
#define CHECK_EQ(x, y) if (CheckEq const& check_eq = CheckEq{(x),(y),((x)==(y))}) \
std::cout << #x << " != " << #y \
<< " (" << check_eq.x_ << " != " << check_eq.y_ << ") "
int main() {
CHECK_EQ(3,4) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
对于我来说,使用和不使用 -O3 都会产生相同的输出
| 归档时间: |
|
| 查看次数: |
4670 次 |
| 最近记录: |