Q_ASSERT发布生成语义
Q_ASSERT release build semantics
我找不到关于发布版本下Q_ASSERT语义的明确声明。如果没有断言检查,那么断言表达式是否被计算?
请考虑以下代码
Q_ASSERT(do_something_report_false_if_failed());
do_something_report_false_if_failed()
会在所有潜在的Qt构建配置下运行吗?这样做会更安全(即使更冗长和可读性更差)吗:
bool is_ok = do_something_report_false_if_failed();
Q_ASSERT(is_ok)
后一种方法的缺点是 ASSERT 失败不那么冗长,但也许它更清楚地表明语句已执行?
在非调试构建配置中不会计算Q_ASSERT
中的表达式。
请考虑以下来自Qt存储库的源代码。
#if !defined(Q_ASSERT)
# ifndef QT_NO_DEBUG
# define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
# else
# define Q_ASSERT(cond) qt_noop()
# endif
#endif
如果定义了QT_NO_DEBUG
,则整个Q_ASSERT
语句将替换为 qt_noop()
,从而删除它以前包含的任何表达式。
切勿依赖 Q_ASSERT
语句中的表达式创建的任何副作用。从技术上讲,仍然可以确保QT_NO_DEBUG
未在特定构建配置中定义,但这不是一个好主意™。
这在 Qt5.5 中似乎有所不同(但不是更早 - 参见 Qt5.4):
#if !defined(Q_ASSERT)
# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
# define Q_ASSERT(cond) do { } while ((false) && (cond))
# else
# define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
# endif
#endif
我现在在Visual Studio 2013中收到很多"警告C4127:条件表达式是常量"。
更新:Qt5.5发行说明说:
Q_ASSERT现在即使在发布模式下也会扩展条件,当 断言被禁用,尽管在无法访问的代码路径中。这 解决有关变量和函数的编译器警告 在发布模式下未使用,因为它们仅用于断言。 不幸的是,隐藏了这些函数和变量的代码库 通过 #ifndef 将需要删除条件才能使用 Qt 5.5 进行编译。
相关文章:
- 我在c++代码中生成了一个运行时#3异常
- 何时在引用或唯一指针上使用移动语义
- Cppcheck生成xml转储文件
- 如何使用CMake编译.proto文件来生成.grpcp.pb.cc和.grpc.pb.h文件
- 如何在C++中使用结构生成映射
- 使用 C/C++ 宏生成函数签名
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 如何从具有移动语义的类对象中生成共享指针
- 生成文件不对文件使用隐式规则
- Boost Spirit,获取迭代器内部语义动作
- boost::asio如何生成多个协同程序,然后加入它们
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- 生成MRPT库时cmake配置失败
- 如何处理使用.ui文件生成的.h文件
- avrogencpp能为模式中的每种类型生成单独的头文件吗
- 在模板基类中为继承类中的可选重写生成虚拟方法
- Q_ASSERT发布生成语义
- 自动隐式生成利用移动语义的因素