面试题答案
一键面试assert()
宏在调试模式下的行为:- 在调试模式下,
assert()
宏用于检查一个条件。如果条件为真,assert()
不做任何事情。如果条件为假,assert()
会向标准错误流(stderr
)输出一条错误信息,其中包含断言失败的源文件名、行号等信息,然后调用abort()
函数终止程序。这有助于开发者在开发过程中快速定位代码中的逻辑错误。例如:
上述代码在调试模式下运行时,会因为#include <cassert> int main() { int a = 10; assert(a == 5); // 这里条件为假,会触发断言失败 return 0; }
assert(a == 5)
条件不成立而输出错误信息并终止程序。- 在调试模式下,
assert()
宏在发布模式下的行为:- 在发布模式下,默认情况下
assert()
宏被定义为空操作(通常通过预处理器定义为#define assert(x) ((void)0)
)。这意味着在发布版本中,所有的assert()
语句都不会生成任何代码,不会影响程序的性能。这样设计是因为发布版本主要面向最终用户,最终用户不需要看到断言失败的错误信息,而且断言检查会增加程序的运行开销,去掉这些检查可以提高程序的运行效率。
- 在发布模式下,默认情况下
- 在发布模式下保留部分
assert()
功能的做法:- 一种常见的做法是自定义一个类似
assert
的宏。例如:
在上述代码中,#ifdef NDEBUG #define MY_ASSERT(x) do { if (!(x)) { /* 自定义处理逻辑 */ } } while (0) #else #define MY_ASSERT(x) assert(x) #endif
NDEBUG
是C++标准库中用于控制assert()
行为的预处理器宏,在发布模式下通常会定义NDEBUG
。通过自定义MY_ASSERT
宏,在调试模式下它等同于标准的assert
,在发布模式下可以在宏定义中实现自己的错误处理逻辑,比如记录日志等,而不是直接终止程序。例如在发布模式下可以这样实现:
这样在发布模式下,当断言条件为假时,会将错误信息记录到#ifdef NDEBUG #include <iostream> #include <fstream> #define MY_ASSERT(x) do { if (!(x)) { std::ofstream log("assert_log.txt"); log << "Assertion failed at some point" << std::endl; } } while (0) #else #define MY_ASSERT(x) assert(x) #endif
assert_log.txt
文件中,而不是终止程序。 - 一种常见的做法是自定义一个类似