对象、引用、函数(包括函数模板特化)和表达式具有称为类型的性质,它限制了对这些实体所容许的操作,并给原本寻常的位序列提供了语义含义。
附加性基本类型及宏
实现定义的空指针常量
NULL
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
#define NULL /*implementation-defined*/ |
宏 NULL
是实现定义的空指针常量,可为
求值为零的整数类型字面常量表达式右值 | (C++11 前) |
零值整数字面量,或为 std::nullptr_t 类型纯右值 | (C++11 起) |
空指针常量可以隐式转换为任何指针类型;这种转换结果是该类型的空指针值。若空指针常量拥有整数类型,它亦可转换为 std::nullptr_t 类型纯右值。
可能的实现
#define NULL 0
// C++11 起
#define NULL nullptr
注意
C 中,宏 NULL
可以拥有类型 void*
,但这在 C++ 中不允许。
调用示例
#include <cstddef>
#include <type_traits>
#include <iostream>
class S;
int main()
{
int* p = NULL;
int* p2 = static_cast<std::nullptr_t>(NULL);
void(*f)(int) = NULL;
int S::*mp = NULL;
void(S::*mfp)(int) = NULL;
if (std::is_same<decltype(NULL), std::nullptr_t>::value)
{
std::cout << "NULL implemented with type std::nullptr_t" << std::endl;
}
else
{
std::cout << "NULL implemented using an integral type" << std::endl;
}
return 0;
}
输出
具有不小于任何基础类型的内存对齐需求的平凡类型
std::max_align_t
定义于头文件 | ||
typedef /*implementation-defined*/ max_align_t; | (C++11 起) |
注意
分配函数,如 std::malloc 所返回的指针,适于为任何对象对齐,这表示其对齐至少与 std::max_align_t 一样严格。
std::max_align_t 通常是最大标量类型的同意词,在大多数平台上是 long double ,而其对齐要求是 8 或 16 。
调用示例
#include <iostream>
#include <cstddef>
int main()
{
std::cout << "alignof(std::max_align_t): "
<< alignof(std::max_align_t) << std::endl;
return 0;
}
输出
从标准布局类型的起始到其指定成员的字节偏移量
offsetof
定义于头文件 | ||
#define offsetof(type, member) /*implementation-defined*/ |
宏 offsetof 展开成 std::size_t 类型的整数常量表达式,其值是从指定类型对象开始到其指定成员的字节数偏移,若有填充字节则包括之。
若 type
不是标准布局类型,则行为未定义 (C++17 前)条件性支持 offsetof
宏的使用 (C++17 起)。
若 member
是 static 成员或成员函数,则行为未定义。
标准布局类型的首个成员的偏移始终是零(空基类优化是强制的)。
表达式 offsetof(type, member)
决不依赖类型,而且它依赖值当且仅当 type 为依赖的。
异常
offsetof
不抛出异常;表达式 noexcept(offsetof(type, member)) 始终求值为 true 。
注意
offsetof
不能以标准 C++ 实现,并要求编译器支持: GCC 、 LLVM
调用示例
#include <iostream>
#include <cstddef>
struct S
{
char c;
double d;
};
int main()
{
std::cout << "the first element is at offset "
<< offsetof(S, c) << std::endl
<< "the double is at offset "
<< offsetof(S, d) << std::endl;
return 0;
}