我们正致力于 Visual Studio (MSVC) 中 Microsoft C/C++ 编译器的标准符合性。 下面概述了 ISO 标准 C 和 C++ 语言,以及依据 Visual Studio 版本的库一致性。 每个 C++ 编译器和标准库功能名称都有一个指向介绍该功能的 ISO 标准 C++ 建议文章的链接(如果在发布时可用)。 “支持”列中列出了首次出现支持该功能的 Visual Studio 版本。
有关一致性改进的详细信息,请参阅 Visual Studio 中的 C++ 一致性改进。 有关其他更改的列表,请参阅 Visual Studio 中 Visual C++ 的新增功能。 若要了解早期版本中的一致性更改,请参阅 Visual C++ 更改历史记录和 2003 至 2015 各版本中 Visual C++ 的新增功能。 若要获取 C++ 团队的最新资讯,请访问 C++ 团队博客。
Note
Visual Studio 2015、2017、2019 和 2022 版本之间没有二进制中断性变更。 有关详细信息,请参阅 Visual Studio 版本之间的 C++ 二进制兼容性
C++ 编译器功能
C++ 标准库功能
GitHub Microsoft STL wiki Changelog 页上提供了按产品版本列出的标准库功能和 bug 修复的详细列表。
一起列出的一组论文表示一项标准功能以及一个或多个批准的改进或扩展。 这些功能可一起实现。
C 标准库功能
| Feature | Supported |
|---|---|
| C99 标准库功能 | Supported |
替代拼写宏 <iso646.h> |
VS 2015 |
宽字符支持 <wchar.h> 和 <wctype.h> |
VS 2015 |
<complex.h> 中的复杂支持 |
在 VS 2015 中部分支持 K |
类型泛型数学函数 <tgmath.h> |
VS 2019 16.8 2104 |
其他浮点特征 <float.h> |
VS 2015 |
十六进制 float printf 说明符 %A、%a |
VS 2015 |
扩展整数类型 <inttypes.h>、<stdint.h> |
VS 2015 |
vscanf 和 <stdio.h> 中的 <wchar.h> 系列 |
VS 2015 |
<math.h> 中的新数学函数 |
VS 2015 |
数学库错误条件处理 (math_errhandling) |
VS 2015 |
浮点环境访问 <fenv.h> |
VS 2015 |
%lf 的 printf 转换说明符 |
VS 2015 |
snprintf 中的 <stdio.h> 函数系列 |
VS 2015 |
boolean 中的 <stdbool.h> 类型 |
VS 2015 |
va_copy 宏 |
VS 2015 |
其他 strftime 转换说明符 |
在 VS 2015 中部分支持 L |
| C11 标准库功能 | Supported |
对齐说明符 <stdalign.h> |
VS 2019 16.8 C11、2104 |
aligned_alloc |
No M |
无返回说明符 <stdnoreturn.h> |
VS 2019 16.8 C11、2104 |
线程处理支持 <threads.h> |
yes |
原子支持 <stdatomic.h> |
experimental |
char16_t、 char32_t<uchar.h> |
VS 2019 16.8 C11 |
删除了 gets() |
VS 2019 16.8 C11、N |
gets_s() |
VS 2019 16.8 C11 |
边界检查接口 (*_s API) |
在 VS 2015 中部分支持 C11、O |
fopen
"x" 选项 |
VS 2019 16.8 C11 |
| Static assertions | VS 2019 16.8 C11、2104 |
quick_exit |
VS 2019 16.8 C11 |
<complex.h> 宏 |
VS 2019 16.8 C11 |
浮点特征 <float.h> |
VS 2019 16.8 C11 |
C11 线程 <threads.h> |
VS 2022 17.8 C11 |
Supported values
否:尚未实现。
部分:实现不完整。 有关详细信息,请参阅说明部分。
VS 2010:在 Visual Studio 2010 中支持的功能。
VS 2013:在 Visual Studio 2013 中支持的功能。
VS 2015:在 Visual Studio 2015 (RTW) 中支持的功能。
VS 2015.2 和 VS 2015.3 分别表示在 Visual Studio 2015 Update 2 和 Visual Studio 2015 Update 3 中支持的功能。
VS 2017 15.0:在 Visual Studio 2017 版本 15.0 (RTW) 中支持的功能。
VS 2017 15.3:在 Visual Studio 2017 版本 15.3 中支持的功能。
VS 2017 15.5:在 Visual Studio 2017 版本 15.5 中支持的功能。
VS 2017 15.7:在 Visual Studio 2017 版本 15.7 中支持的功能。
VS 2019 16.0:在 Visual Studio 2019 版本 16.0 (RTW) 中支持的功能。
VS 2019 16.1:在 Visual Studio 2019 版本 16.1 中支持的功能。
VS 2019 16.2:在 Visual Studio 2019 版本 16.2 中支持的功能。
VS 2019 16.3:在 Visual Studio 2019 版本 16.3 中支持的功能。
VS 2019 16.4:在 Visual Studio 2019 版本 16.4 中支持的功能。
VS 2019 16.5:在 Visual Studio 2019 版本 16.5 中支持的功能。
VS 2019 16.6:在 Visual Studio 2019 版本 16.6 中支持的功能。
VS 2019 16.7:在 Visual Studio 2019 版本 16.7 中支持的功能。
VS 2019 16.8:在 Visual Studio 2019 版本 16.8 中支持的功能。
VS 2019 16.9:在 Visual Studio 2019 版本 16.9 中支持的功能。
VS 2019 16.10:在 Visual Studio 2019 版本 16.10 中支持的功能。
VS 2022 17.0:在 Visual Studio 2022 版本 17.0 中支持的功能。
VS 2022 17.1:在 Visual Studio 2022 版本 17.1 中支持的功能。
VS 2022 17.2:在 Visual Studio 2022 版本 17.2 中支持的功能。
VS 2022 17.3:在 Visual Studio 2022 版本 17.3 中支持的功能。
VS 2022 17.4:在 Visual Studio 2022 版本 17.4 中支持的功能。
VS 2022 17.5:在 Visual Studio 2022 版本 17.5 中支持的功能。
Notes
A 在 /std:c++14 模式下,动态异常规范仍没有实现,且 throw() 仍被视为 __declspec(nothrow) 的同义词。 在 C++17 中,动态异常规范大部分已被 P0003R5 删除,一个残留部分除外:throw() 已被弃用,并被要求与 noexcept 同义。 在 /std:c++17 模式下,MSVC 现在通过赋予 throw() 与 noexcept 相同的行为(即通过终止强制执行)来符合标准。
编译器选项 /Zc:noexceptTypes 请求获取 __declspec(nothrow) 的旧行为。 将来版本的 C++ 中可能会删除 throw()。 为了有助于迁移代码来响应标准和 Microsoft 实现中的这些更改,在 /std:c++17 和 /permissive- 下添加了针对异常规范问题的新编译器警告。
B 在 /permissive- 模式下的 Visual Studio 2017 版本 15.7 中受支持。 有关详细信息,请参阅 Two-phase name lookup support comes to MSVC。
C 在 Visual Studio 2019 版本 16.6 和更高版本中,编译器通过 /Zc:preprocessor 选项来完全实现标准 C99 预处理器。 (从 Visual Studio 2017 版本 15.8 到 16.5,编译器通过 /experimental:preprocessor 编译器选项支持标准 C99 预处理器。)指定编译器选项 /std:c11 或 /std:c17 时,此选项默认处于启用状态。
D 在 /std:c++14 下受支持,但出现可取消的警告 C4984。
E 实现足以支持 C++20 标准库。 完整实现需要二进制中断性变更。
F 指定 /std:c++17 或更高版本的编译器选项会导致功能被删除。 要重新启用这些功能(以轻松转换为较新的语言模式),请使用下面这些宏:_HAS_AUTO_PTR_ETC、_HAS_FUNCTION_ALLOCATOR_SUPPORT、_HAS_OLD_IOSTREAMS_MEMBERS 和 _HAS_UNEXPECTED。
G C++17 的并行算法库是完整的。 “完整”并不意味着每种算法在各种情况下都是并行执行的。 最重要的算法已并行执行。 即使实现不并行执行算法,也会提供执行策略签名。 中心内部标头 <yvals_core.h> 中包含以下“并行算法注释”:C++ 允许实现将并行算法作为系列算法的调用实现。 此实现并行执行几个常见算法调用,但不是全部。
以下算法并行执行:
-
adjacent_difference、adjacent_find、、all_of、any_ofcountcount_ifequalexclusive_scanfindfind_endfind_first_offind_iffind_if_notfor_eachfor_each_ninclusive_scanis_heapis_heap_untilis_partitionedis_sortedis_sorted_untilmismatchnone_ofpartitionreduceremoveremove_ifreplacereplace_ifsearchsearch_nset_differenceset_intersectionsortstable_sorttransformtransform_exclusive_scantransform_inclusive_scantransform_reduce
这些算法目前还没有被并行化:
- 这些算法表明目标硬件上的并行性能没有显著提升。 只用于复制或置换无分支的元素的所有算法通常会受内存带宽限制:
-
copy、、copy_n、fillfill_n、move、reversereverse_copyrotaterotate_copy、shift_left、、shift_rightswap_ranges
-
- 这些算法在对用户并行性要求方面存在混淆;可能出现在上述类别中:
-
generate、generate_n
-
- 这些算法的有效并行性可能不可行:
-
partial_sort、partial_sort_copy
-
- 这些算法尚未进行评估。 库可能在将来的版本中实现并行化:
-
copy_if、、includes、inplace_mergelexicographical_compare、max_element、mergemin_element、minmax_elementnth_elementpartition_copyremove_copyremove_copy_ifreplace_copyreplace_copy_ifset_symmetric_differenceset_unionstable_partitionuniqueunique_copy
-
H 此为全新实现,与之前的 std::experimental 版本不兼容,这对符号链接支持、bug 修复以及更改必须符合标准的行为而言是必不可少的。 目前,<filesystem> 同时提供新的 std::filesystem 和以前的 std::experimental::filesystem。
<experimental/filesystem> 标头只提供旧的实验性实现。 在下一突破性 ABI 版本的库中,实验性实现将被删除。
Jstd::byte 由 /std:c++17 或更高版本启用,但由于它在某些情况下可能会与 Windows SDK 标头冲突,因此它有细化的选择退出宏。 若要禁用它,请将 _HAS_STD_BYTE 定义为 0。
K MSVC 不支持 _Complex 关键字或本机复杂类型。 通用 CRT <complex.h> 使用特定于实现的宏来达到同样的效果。 有关详细信息,请参阅 C 复杂数学支持。
L 通用 CRT 不实现 strftimeE 和 O 替代转换修饰符。 这些修饰符将被忽略(例如,%Oe 的行为与 %e 相同)。 基础区域设置 API 不支持这些修饰符。
M 通用 CRT 不实现 C11 aligned_alloc,但提供 _aligned_malloc 和 _aligned_free。 由于 Windows 操作系统不支持对齐的分配,因此不太可能实现此函数。
O 某些边界检查函数未实现,或者具有不同的签名,或者不是 C11 或 C17 标准的一部分。 以下函数未实现:abort_handler_s、ignore_handler_s、memset_s、set_constraint_handler_s、snprintf_s、snwprintf_s、strerrorlen_s、vsnwprintf_s。 以下函数具有不同的签名:gmtime_s、localtime_s、qsort_s、strtok_s、vsnprintf_s、wcstok_s。 以下函数不会出现在标准中:clearerr_s、fread_s。
P Visual Studio 2019 版本 16.10 中增加了支持。 在 Visual Studio 2022 版本 17.0 中增加了对 Clang 的支持。
Q 这会删除 declare_reachable、undeclare_reachabledeclare_no_pointers、undeclare_no_pointers、get_pointer_safety。 以前,这些函数不起作用。
R 这是常见的源中断性变更。 但是,以前在运行时具有未定义行为的代码现在会被拒绝并出现编译器错误。
S 输入范围适配器,counted_iterator 在 VS 2022 17.0 中实现。 Visual Studio 2019 版本 16.11 的未来更新计划纳入这些更改。
T 以 C++ 编译时 (<stdatomic.h>),当前支持 /std:c++latest。 以 C 编译时(/std:c11 和 /std:c17)尚不支持
14 即使指定了 /std:c++14(默认值),这些 C++17 和 C++20 功能也始终处于启用状态。 这是因为在引入 /std 选项之前实现了该功能,或者因为条件实现异常复杂。
17 这些功能由 或更高版本编译器选项启用/std:c++17。
20 在 Visual Studio 2019 版本 16.10 的所有版本中,这些功能由 /std:c++latest 编译器选项启用。 Visual Studio 2019 版本 16.11 添加了 /std:c++20 编译器选项以实现这些功能。
20abi 由于发布后仍在不断改进 C++20 标准 <format>,因此 <chrono> 的格式部分(它依赖于 <format>),还有 <ranges> 中的范围工厂和范围适配器(这都需要 view 概念)都只能在 下使用/std:c++latest。 与 WG21 达成无需进一步 ABI 中断性变更的协议后,预计这些功能将位于 /std:c++20 下。 在 Visual Studio 2019 版本 16.11 和更高版本中,在 <chrono> 编译器选项下启用 /std:c++20 的其余部分和适用于范围的算法。
23 在 Visual Studio 2022 版本 17.0 和更高版本中,这些功能由 /std:c++latest 编译器选项启用。
C11 编译器对 C11 和 C17 的支持需要 Visual Studio 2019 版本 16.8 或更高版本。 除非另有注明,否则 C11 和 C17 库支持需要 Windows SDK 内部版本 10.0.20211.0 或更高版本。 若要详细了解如何安装对 C11 和 C17 的支持,请参阅在 Visual Studio 中安装 C11 和 C17 支持。
DR 这些功能在所有 C++ /std 编译器选项模式中启用。 C++ 标准委员会将此更改作为对 C++ 11 和所有更高版本的追溯缺陷报告。
2104 C11 库对此功能的支持需要 Windows SDK 内部版本 10.0.20348.0(版本 2104)或更高版本。
See also
C++ 语言参考
C++ 标准库
Visual Studio 中的 C++ 符合性改进
Visual Studio 中 Visual C++ 的新增功能
Visual C++ 更改历史记录 (2003 - 2015)
Visual C++ 新增功能 (2003 - 2015)
C++ 团队博客