1. 预定义标识符( __func__标识符),返回函数名字
//__func__预定义标识符,返回所在函数的名字
#include <iostream>
#include <string>
using namespace std;
const char* hello() { return __func__; } //return "hello";返回函数名
const char* world() { return __func__; }
int main()
{
std::cout << hello() << "," << world(); //hello, world
}
在上述代码中,我们定义了两个函数hello() 和 world(),并利用__func__返回函数名字。事实上,按照标准定义,编译器会隐式的在函数的定义之后定义__func__标识符。比如上面的函数hello()实际上的定义等同于下面代码:
const char* hello() {
static const char* __func__ = "hello";
return __func__;
}
预定义标识符__func__对于轻量级的调试代码具有非常重要的作用。而在 c++11中,标准允许其使用在类或结构体中。可以看看下面的例子:
struct TestStruct {
TestStruct() : name(__func__) {
}
const char* name;
};
int main()
{
TestStruct ts;
cout << ts.name << endl; // TestStruct
}
上述代码中,在结构体的构造函数中,初始化成员列表使用__func__预定义标识符是可行的,其效果跟在函数中使用一样。
注意: 将__func_作为默认值是不允许的
void funFail(string funName = __func__) {}; //无法编译通过
2. 变量参数的宏定义及__VA_ARGS__
预定义宏__VA_ARGS__可以在宏定义的实现部分替换省略号所代表的的字符串。
#define PR(...) printf(__VA_ARGS__)
事实上,变长参数宏与 printf 是一对好搭档。
#include <stdio.h>
#define LOG(...) {\
fprintf(stderr, "%s: Line: %d\t", __FILE__, __LINE__);\
fprintf(stderr, __VA_ARGS__);\
fprintf(stderr, "\n");\
}
int main()
{
int x = 3;
LOG("x = %d", x);
}
//E:\C++\ConcurrentApplication\ConcurrentApplication\ConcurrentApplication.cpp: Line: 29 x = 3
定义LOG宏用于记录代码位置中的一些信息。
3. long long 整型
long long 整型有两种:long long 和 unsigned long long。在 c++11 中,标准要求 long long 整型可以在不同的平台上有不同的长度,但至少有 64 位。我们在写常数字面量时可以使用 LL(或者ll)标识一个long long 类型的字面量,而 ULL(或 ull、Ull、uLL)标识一个 unsigned long long 类型的字面量。比如:
long long int lli = -900LL;
unsigned long long int ulli = 900ULL;
同其他类型一样,要了解平台上 long long 大小的方法就是查看(或<limits.h>中的宏)。与 long long 整型相关的一共有3个:LLONG_MIN、LLONG_MAX、ULLONG_MAX。他们分别代表了平台上最小的 long long 值、最大的 long long 值、最大的 unsigned long long 值。
#include <climits>
int main()
{
//=============== climits中查看 long long 长度 ==================
long long llmax = LLONG_MAX;
long long llmin = LLONG_MIN;
unsigned long long ullmax = ULLONG_MAX;
printf("max of long long: %lld \n", llmax);
printf("min of long long: %lld \n", llmin);
printf("max of unsigned long long: %llu \n", ullmax);
}
//输出:
//max of long long: 9223372036854775807
//min of long long: -9223372036854775808
//max of unsigned long long: 18446744073709551615
4. 宏 __cplusplus
宏 __cplusplus 通常被定义一个整型值。而且随着标准的变化,__cplusplus 宏一般是一个比以往标准中更大的值。比如在 c++03 标准中,__cplusplus 的值被定义为 199711L,而在 c++11 标准中,宏 __cplusplus 的值被定义为 201103L。这点变化可以为代码所用。比如程序员想确定代码是使用 c++11 编辑器编译时,可以使用如下代码:
#if __cplusplus < 201103L
#error "should use c++11 implementation."
#endif
在 C 和 C++ 混合编写的代码中,常常会在头文件看到如下声明;
#ifdef __cplusplus
extern "C" {
#endif
//一些代码
#ifdef __cplusplus
}
#endif
这是 C 与 C++ 混用头文件的典型做法。
5. 静态断言与 static_assert
assert 宏:运行时期的断言 。
static_assert:编译时期的断言。
static_assert 使用起来非常简单。接收两个参数,一个是断言表达式,这个表达式通常需要返回一个表达式;一个是警告信息,通常是一个字符串。
static_assert(sizeof(int) == 8, "this 64 bit machine should follow this!");
int main() {
return 0;
}
将 static_assert 写在函数体外是较好的选择。
必须注意的是:
static_assert 的表达式必须是在编译时期可以计算的表达式,即必须是常量表达式。