这一章包括一些C++17中的总体性的内容。
这个预处理值代表当前C++的版本,现在__cplusplus
应该被定义为201703L
。
然而,注意Visual C++在所有模式下的默认值仍然是199711
。
为了纠正这个行为,可以使用编译选项/Zc:__cplusplus
,见如下讨论:
http://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus
C++17以C11为基础,而不是C99,后者是C++14的基础。
这意味着C++17将从C11引入的特性中受益,但也必须做出相应的修改。 然而,还有各种约束:
- C11标准引入了一些为了“更安全的编程”设计的函数和宏来替代传统的可能导致例如
覆写无限数量的内存等问题的函数和宏。它们中的大多数有后缀
_s
。例如, C11引入了strcpy_s()
、sprintf_s()
函数接受一个额外的参数表示大小 来保证它们不会覆写一个长度不够的字符序列。
在C11中,这些函数和之前的不安全的版本在同一个头文件中。
然而在相应的C++17头文件中,它们 不 在命名空间std
中。
当包含了相应的头文件后它们是否会出现在全局命名空间中是实现定义的。
- 新的C头文件
<stdatomic.h>
、<stdnoreturn.h>
、<threads.h>
被 忽略并且在C++中没有对应的内容。 - 对头文件
<ccomplex>
、<cstdalign>
、<cstdbool>
、<ctgmath>
的使用已经被废弃。
作为兼容C11的一个副作用,C++17澄清了信号处理器中可以使用哪些调用和函数。
C++17引入了术语 信号安全 求值。根据它的定义,下列操作不能出现在信号处理器中:
- 调用任何标准库函数(除非显式声明了是信号安全的)
- 调用
new
或者delete
(除非使用了信号安全的内存分配器) - 使用
thread_local
对象 - 使用
dynamic_cast
- 抛出异常或者进入
try
语句块 - 执行或等待具有静态生命周期的变量的首次初始化
下面的函数是信号安全的并且可以被调用:
abort()
和_Exit()
quick_exit()
,前提是用at_quick_exit()
注册的函数是线程安全的memcpy()
和memmove()
std::numeric_limits<>
的所有成员函数std::initializer_lists
的所有成员函数- 所有类型特征
C++17澄清了一个程序“make progress”(取得进展)或者“block”(阻塞)的含义。
参见https://wg21.link/p0072r1获取有关这个话题的进一步讨论。