宏定义与C语言跨平台问题
背景知识
C/C++ 通常使用宏来做跨平台的功能,这个功能又依赖于你系统上安装的编译器内置的宏。 比如说我在一台 linux 主机上可以看到如下宏。
gcc -dM -E -x c /dev/null | grep -i linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1
同样的命令我在 mac 上就不会看到 linux 系统相关的宏定义。
gcc -dM -E -x c /dev/null | grep -i linux
但是可以看到 mac 相关的宏定义。
gcc -dM -E -x c /dev/null | grep -i __APPLE__
#define __APPLE__ 1
C语言跨平台程序例子
因为编译器知道它现在运行在哪个系统上,编译器又通过宏把这个信息告诉了程序员;所以程序员只要检查对应平台的宏是否存在,然后执行相应的代码就行了。
#include <stdio.h>
int main(int argc, char **argv)
{
#ifdef __APPLE__
printf("runing in mac os .");
#elif __linux__
printf("running in linux os .");
#endif
return 0;
}
- 在 linux 下编译运行的效果如下:
gcc main.c && ./a.out
running in linux os .
- 在 mac 下编译运行的效果如下:
gcc main.c && ./a.out
runing in mac os
自定义宏
我们不只是能使用编译器已经定义好的宏,还能把我们定义的宏告诉编译器;下面定义一下叫 "_EXAMPLE_AGE" 的宏,默认值是 100 ,当然我们可以告诉编译器覆盖这个值。
#include <stdio.h>
#ifndef _EXAMPLE_AGE
/* 如果没有定义 _EXAMPLE_AGE 这个宏就给一个默认值 100
* 上面说的“没有定义”其实就是说的编译里 gcc 有没有加上对应的宏定义
*/
#define _EXAMPLE_AGE 100
#endif
int main(int argc, char **argv)
{
printf("_EXAMPLE_AGE = %d \n", _EXAMPLE_AGE);
return 0;
}
当我们不告诉编译器宏的值时,编译器会使用我们定义的默认值。
gcc main.c && ./a.out
_EXAMPLE_AGE = 100
当我们告诉编译器宏的值是多少时,默认值就被覆盖。
gcc -D_EXAMPLE_AGE=10086 main.c && ./a.out
_EXAMPLE_AGE = 10086