C/C++常用的预编译宏

我们有时需要使用 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 计算表达式并检查真值,可以执行复合条件

参考资料