前言

在.c和.cpp混用的时候,注意到了它们在处理函数的时候有所不同
然后通过#ifndef _cplusplus去规避。那么这个_cplusplus就是c++的预定义宏


正文

func

__func__
编译器支持iso c99和iso c++11指定的预定义标识符
它的作用就是代表函数的名称

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>

void hhh(){
std::cout << __func__ << "\n";
}

int main(){
std::cout << __func__ << "\n";
hhh();

return 0;
}

这种替换成函数名的操作,适用于debug的时候给函数做标记,看看是卡在哪个函数了。


标准预定义宏

说明
__DATE__ 源文件的编译器日期
__TIME__ 当前转换单元的转换时间
__FILE__ 源文件的名称
__LINE__ 当前的行号
__cplusplus 当翻译单元为c++时,__cplusplus定义为一个整数文本,否则未定义。

编译器支持iso c99和iso c++11指定的预定义标识符
老样子都是这个标准开始。

1
2
3
4
5
std::cout << __func__ << "\n";
std::cout << __DATE__ << "\n";
std::cout << __TIME__ << "\n";
std::cout << __FILE__ << "\n";
std::cout << __cplusplus << "\n";

可以自己打印玩玩:

这里的cplusplus按照设计应该是输出当前所使用的c++标准,比如年和月,但这里可能没做什么处理,都是197711.
不过也够区分c和c++了。


msvc预定义宏

说明
_CHAR_UNSIGNED 如果char类型为无符号,则该定义为1,否则未定义
__COUNTER__ 从0开始,每次使用都会递增1
_DEBUG 如果设置了/lDd/mDd/mTd 则该定义为1,否则未定义
__FUNCTION__ 函数名称 不含修饰符
__FUNCDNAME__ 函数名称 包含修饰符
__FUNCSIG__ 包含了函数签名的函数名
_WIN32 当编译为32位ARM、64位ARM、X86或X64定义为1,否则未定义
_WIN64 当编译为64位ARM或者X64定义为1,否则未定义
__TIMESTAMP__ 最后一次源代码修改时间和日期

除了c++标准预定义的宏,一些大的ide也会在编译器内置一些预定义宏,就拿vs来说。


_CHAR_UNSIGNED

1
2
3
4
5
6
7
int main(){
#ifdef _CHAR_UNSIGNED
std::cout << "unsigned char\n";
#endif

return 0;
}

能看到没有设置无符号的char时他是灰色的不起作用。
判断字符有无符号,同样可以实现两种不同的效果。


__COUNTER__

1
2
3
4
5
6
7
int main(){
__COUNTER__;
std::cout << __COUNTER__ << std::endl;
std::cout << __COUNTER__ << std::endl;
std::cout << __COUNTER__ << std::endl;
std::cout << __COUNTER__ << std::endl;
}

像这种出现几次就会从0开始累计的,早的时候可能都还要设置一个变量累加,既然有预定义的宏直接用也不是不行。
但是也要注意只能在vs类的ide上才有效。


_DEBUG

debug的场景可能比较多。因为咋样都要调试,可以在里面设置显示一些调试信息。

1
2
3
#ifdef _DEBUG
std::cout << "debug";
#endif // _DEBUG

明眼人就知道,这个debug就跟你项目上面设置的有关。如果是release模式,debug就失效了。


后面几个

不常用。。自己随便试试就行了。

1
2
3
   std::cout << __FUNCTION__ << std::endl;
std::cout << __FUNCDNAME__ << std::endl;
std::cout << __FUNCSIG__ << std::endl;
1
2
3
4
5
6
void hhh(){
std::cout << __func__ << "\n";
std::cout << __FUNCTION__ << std::endl;
std::cout << __FUNCDNAME__ << std::endl;
std::cout << __FUNCSIG__ << std::endl;
}

可能main函数不明显

_WIN32 和 _WIN64 属于架构问题。
在vs ide上能指定x86和x64,_WIN64才是只有当项目是x64编译的时候才为1。

__TIMESTAMP__ 显示的比较全,年月日 小时分钟秒 星期几都会显示。


结语

除了标准预定义的宏可以通用,其他的编译器自己预定义的没有可移植性,所以用的时候要注意