2024年C C++最全C++ Visual Studio 2022 中的改进、行为更改和错误修复_c++修复,C C++驱动面试

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

Visual Studio 2022 版本 17.4 中的一致性改进

Visual Studio 2022 版本 17.4 包含 Microsoft C/C++ 编译器中的以下一致性改进、错误修复和行为更改

作用域的基础类型没有固定类型enum

在 Visual Studio 2022 版本 17.4 之前的 Visual Studio 版本中,C++编译器未正确确定没有固定基类型的无作用域枚举的基础类型

C++ 标准要求**枚举的基础类型足够大,以容纳该枚举中的所有枚举器。足够大的枚举器可以将枚举的基础类型设置为无符号 int、long long 或无符号** long long。以前,无论枚举器值如何,此类**枚举类型在 Microsoft 编译器中始终具有基础类型int**

启用后,/Zc:enumType选项是潜在的源和二进制中断性更改。默认情况下,它处于关闭状态,并且不由/允许启用,因为修复可能会影响二进制兼容性。启用一致性修复时,某些枚举类型会更改大小。某些 Windows SDK 标头包含此类枚举定义。

#include<stdio.h>
enum Unsigned
{
    A = 0xFFFFFFFF //值“A”不适合“int”。
};

//以前,未通过此static_assert。现在使用 /Zc:enumTypes 传递。
static_assert(std::is_same_v<std::underlying_type_t<Unsigned>, unsigned int>);

template <typename T>
void f(T x)
{
}

int main()
{
    // 以前称为 f<int>,现在称为 f<unsigned int>。
    f(+A);
}

//以前,这个枚举将具有底层类型的“int”,但标准C++要求它具有
//64 位基础类型。使用 / Zc:enumTypes 将此枚举的大小从 4 更改为 8,这可能会
//影响与使用早期编译器版本或不使用开关编译的代码的二进制兼容性。
enum Changed
{
    X = -1,
    Y = 0xFFFFFFFF
};

定义中没有固定基础类型的枚举器类型enum

在 Visual Studio 2022 版本 17.4 之前的 Visual Studio 版本中,C++编译器未正确确定没有固定基类型的无作用域枚举的基础类型

C++ 标准要求**枚举的基础类型足够大,以容纳该枚举中的所有枚举器。足够大的枚举器可以将枚举的基础类型设置为无符号 int、long long 或无符号** long long。以前,无论枚举器值如何,此类**枚举类型在 Microsoft 编译器中始终具有基础类型int**。

启用后,/Zc:enumType选项是潜在的源和二进制中断性更改。默认情况下,它处于关闭状态,并且不由/允许启用,因为修复可能会影响二进制兼容性。启用一致性修复时,某些枚举类型会更改大小。某些 Windows SDK 标头包含此类枚举定义。

举例

enum Enum {
    A = 'A',
    B = sizeof(A)
};

static_assert(B == 1); // 以前失败,现在在 /Zc:enumType 下成功

枚举器应在枚举的右大括号之前具有**char**类型,因此应使用 进行初始化。在 /Zc:enumType修复之前,具有枚举类型,具有推导的底层类型int,并使用 或 4 进行初始化。A``B``sizeof(char)``A``Enum``B``sizeof(Enum)

Visual Studio 2022 版本 17.3 中的一致性改进

Visual Studio 2022 版本 17.3 包含 Microsoft C/C++ 编译器中的以下一致性改进、错误修复和行为更改。

改进了指针之间的修饰符兼容性检查

尤其是 C 编译器没有正确比较指针之间的修饰符。此缺陷可能导致对两者之间的不相容性和两者之间的不相容性诊断不正确

void fn(void* pv) { (pv); }

int main()
{
    int t = 42;
    int* pt = &t;
    int* volatile * i = &pt;
    fn(i);    // 现在支持 C4090
    const int** j = &pt;
    fn(j);    //不再支持C4090
 }

Visual Studio 2022 版本 17.2 中的一致性改进

Visual Studio 2022 版本 17.2 包含 Microsoft C/C++ 编译器中的以下一致性改进、错误修复和行为更改。

未终止的双向字符警告

  • Visual Studio 2022 版本 17.2 为注释和字符串中未终止的 Unicode 双向字符添加了 3 级警告 C5255
    • 警告 C5255 仅处理转换后包含 Unicode 双向字符的文件。此警告适用于 UTF-8、UTF-16 和 UTF-32 文件,因此必须提供正确的源编码。此更改是源中断性更改。

示例(之前/之后)

代码举例

// bidi.cpp
int main() {
    const char *access_level = "user";
    
    //以下源代码行包含等效于的双向 Unicode 字符:
    if ( strcmp(access_level, “user‮ ⁦// Check if admin ⁩ ⁦”) ) {
    在大多数编辑器中,它呈现为:    if ( strcmp(access_level, "user") ) { // Check if admin
    if ( strcmp(access_level, "user‮ ⁦// Check if admin ⁩ ⁦") ) {
        printf("You are an admin.\n");
    }
    return 0;
}
/* 构建输出
双向.cpp(8): 警告 C5255:遇到未终止的双向字符:“U+202e”
双向.cpp(8): 警告 C5255:遇到未终止的双向字符:“U+2066”
*/

from_chars() float

  • Visual Studio 2022 版本 17.2 修复了产生错误结果的错误破坏规则。此错误影响了位于连续值的精确中点的十进制字符串,范围很窄。(受影响的最小值和最大值分别为 and。决胜规则想要舍入为“偶数”,“偶数”恰好是“向下”,但实现错误地舍入了“向上”

// 
#include <cassert>
#include <charconv>
#include <cstdio>
#include <string_view>
#include <system_error>
using namespace std;
int main() {
    const double dbl  = 32768.009765625;
    const auto sv     = "32768.009765625"sv;
    float flt         = 0.0f;
    const auto result = from_chars(sv.data(), sv.data() + sv.size(), flt);
    assert(result.ec == errc{});
    printf("from_chars() returned: %.1000g\n", flt);
    printf("This rounded %s.\n", flt < dbl ? "DOWN" : "UP");
}
  • 在 Visual Studio 2022 版本 17.2 之前的版本中:
  • 输出
C:\Temp>cl /EHsc /nologo /W4 /std:c++17 from_chars_float.cpp && from_chars_float
from_chars_float.cpp
from_chars() returned: 32768.01171875
This rounded UP.
  • 在 Visual Studio 2022 版本 17.2 及更高版本中:

输出

C:\Temp>cl /EHsc /nologo /W4 /std:c++17 from_chars_float.cpp && from_chars_float
from_chars_float.cpp
from_chars() returned: 32768.0078125
This rounded DOWN.
__STDC__使可用于 C__STDC__
  1. C 标准要求符合 C 的实现定义为 。由于 UCRT 的行为,它不会公开 POSIX 函数,因此默认情况下,如果不对稳定语言版本进行重大更改,则无法为 C 定义此宏
  2. 此更改是源中断性更改。当启用 C11 或 C17 模式时,它适用,/std:c11 或 /std:c17,以及 /Zc:__STDC__
// test__STDC__.c
#include <io.h>
#include <fcntl.h>
#include <stdio.h>

int main() {
#if __STDC__
    int f = _open("file.txt", _O_RDONLY);
    _close(f);
#else
    int f = open("file.txt", O_RDONLY);
    close(f);
#endif
}

/* 命令行行为

C:\Temp>cl /EHsc /W4 /Zc:__STDC__ test__STDC__.c && test__STDC__

*/

缺少括号的警告

  • 警告 C5246 报告在子对象的聚合初始化期间缺少大括号。在 Visual Studio 2022 版本 17.2 之前,警告无法处理匿名者的情况。structunion
  • 此更改是源中断性更改。当启用默认关闭警告 C5246 时,它适用。

  • 在 Visual Studio 2022 版本 17.2 及更高版本中,此代码现在会导致错误:
struct S {
   union {
      float f[4];
      double d[2];
   };
};

void f()
{
   S s = { 1.0f, 2.0f, 3.14f, 4.0f };
}

/* Command line behavior
cl /Wall /c t.cpp

t.cpp(10): warning C5246: '匿名结构或联合':子对象的初始化应括在大括号中‘
*/
  • 若要解决此问题,请向初始值设定项添加大括号
void f()
{
   S s = { { 1.0f, 2.0f, 3.14f, 4.0f } };
}

Visual Studio版本 17.1 中的一致性改进

Visual Studio 2022 版本 17.1 包含 Microsoft C/C++ 编译器中的以下一致性改进、错误修复和行为更改。

  • C++ 标准仅允许块作用域中的 lambda 表达式具有捕获默认值。在 Visual Studio 2022 版本 17.1 及更高版本中,编译器会检测何时不允许在非本地 lambda 表达式中使用捕获默认值。它会发出新的 4 级警告 C5253。
  • 此更改是源中断性更改。它适用于使用新lambda处理器的任何模式:/Zc:lambda,/std:c++20或/std:c++****latest

在 Visual Studio 2022 版本 17.1 中,此代码现在发生错误:

#pragma warning(error:5253)

auto incr = [=](int value) { return value + 1; };

//capture_default.cpp(3,14):错误 C5253:非本地 lambda 不能具有捕获默认值
自动增量 = [=](整数值) { 返回值 + 1; };
//             ^

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

地 lambda 不能具有捕获默认值
自动增量 = [=](整数值) { 返回值 + 1; };
// ^




[外链图片转存中...(img-KDVMdOjJ-1715522658854)]
[外链图片转存中...(img-jhN6l8nc-1715522658855)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值