#include与#define位置的相对关系可能会影响程序的运行
例如
#include<iostream>
#define NDEBUG
#include<cassert>
// #define NDEBUG
int main(){
assert(0);
std::cout << "hello world!" << std::endl;
return 0;
}
运行后,输出 hello world!
而下段代码运行后
#include<iostream>
#define NDEBUG
#include<cassert>
// #define NDEBUG
int main(){
assert(0);
std::cout << "hello world!" << std::endl;
return 0;
}
assert输出信息,终止程序运行。
究其原因,是#include<cassert>
与#define NDEBUG
均在预处理过程中展开,观察cassert的源代码。
/*
* assert.h
* This file has no copyright assigned and is placed in the Public Domain.
* This file is a part of the mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within the package.
*
* Define the assert macro for debug output.
*
*/
/* We should be able to include this file multiple times to allow the assert
macro to be enabled/disabled for different parts of code. So don't add a
header guard. */
#ifndef RC_INVOKED
/* All the headers include this file. */
#include <_mingw.h>
#undef assert
#ifdef __cplusplus
extern "C" {
#endif
#ifdef NDEBUG
/*
* If not debugging, assert does nothing.
*/
#define assert(x) ((void)0)
#else /* debugging enabled */
/*
* CRTDLL nicely supplies a function which does the actual output and
* call to abort.
*/
_CRTIMP void __cdecl __MINGW_NOTHROW _assert (const char*, const char*, int) __MINGW_ATTRIB_NORETURN;
/*
* Definition of the assert macro.
*/
#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))
#endif /* NDEBUG */
#ifdef __cplusplus
}
#endif
#endif /* Not RC_INVOKED */
预处理器实际是将头文件的内容插入当前文件位置。所以#define NDEBUG与#include<cassert>的相对位置会影响程序运行结果。而在编译命令中使用 -D NDEBUG则不会产生该情况。