我们有时需要使用 C/C++ 编写一个多功能的项目,根据实际情况,选择不同的编译内容,从而产生不同的可执行程序,也就是条件编译。
- 判定当前编译的操作系统,对于不同平台下的操作,比如创建文件夹
mkdir
- 确定当前的编译环境,有可能在VS下编译,也有可能在 Gcc 下编译
- 区分编译选项。在Debug模式下大量输出或者打印变量信息,在Release模式下禁用此类输出
- 判定当前编译使用的C/C++标准
- 自定义模块。
这个时候,最好采用预编译宏来控制编译结果,使得同一份代码满足多项需求。
本文不涉及一些预编译宏的高级用法,比如使用预编译宏来实现嵌入汇编。
1. 判定当前的操作系统
__WIN32
, __linux__
,__MACOS__
分别用来判定当前操作系统是否为 Windows,Linux或MacOS。
#ifdef __WIN32
#endif
#ifdef __WIN64
#endif
2. 判定当前的编译环境
尽管我认为纯C/C++项目,最好脱离VS。但是日常事件中还是需要与VS打交道,因此需要判定项目是否是在VS环境中编译
#ifdef _MSC_VER
// 专属VS编译环境下的代码
#else
// ...
#endif
比如下列代码,可以在VS环境下,禁止VS输出4996号错误。在其他环境下丝毫没有影响
#ifdef _MSC_VER
#pragma warning( disable : 4996)
#endif
其他编译环境的判定如下
#ifdef __clang__
/*code specific to clang compiler*/
#elif __GNUC__
/*code for GNU C compiler */
#elif _MSC_VER
/*usually has the version number in _MSC_VER*/
/*code specific to MSVC compiler*/
#elif __BORLANDC__
/*code specific to borland compilers*/
#elif __MINGW32__
/*code specific to mingw compilers*/
#endif
3. 判定当前的编译模式
4. 其他有用的预定义宏
4.1 程序名称
__FILE__
,代码所在文件名__LINE__
,代码所在行号__func__
,代码所在函数名称__DATE__
,打印编译日期__TIME__
,打印编译时间__STDC__
,__STDC_VERSION__
,cpp版本号
#include <stdio.h>
int main(){
printf("FILE: %s\n",__FILE__);
printf("LINE: %d\n",__LINE__);
printf("func: %s\n",__func__);
printf("TIME: %s %s\n",__DATE__, __TIME__);
printf("STDC: %d\n",__STDC__);
printf("CVER: %ld\n",__STDC_VERSION__);
}
输出
FILE: test.c
LINE: 5
func: main
TIME: May 13 2025 15:59:39
STDC: 1
CVER: 201710
4.2 解决头文件嵌套包含
4.3 其他有用的预定义宏
#error
#pragma
#line
4. 自定义模块
#ifdef
检查是否已定义该名称的宏,只能使用一个条件
#if defined
计算表达式并检查真值,可以执行复合条件