C++中switch

C++中switch...case绕过变量初始化

之前和同事遇到一个编译错误,顺便了解了一下标签下变量的作用域与绕过初始化的问题。总结就是,要在switch​语句中,除非声明包含在块中,否则不能跳过带有初始值设定项的声明。注意这里C++的表现和C语言不同。

编译环境

Visual Studio 2022 / v143 / C++17

下面的代码是不能够通过编译的

#include <iostream>
int main()
{
    switch (0) {
    case 1:
        int b = 1;
        break;
    default:
        break;
    }
    return 0;
}

如果进行了初始化操作,但是此时跳过了该变量的初始化是非法的操作, 造成无法预料的结果。

不限于switch语句。使用"goto"跳过初始化也会遇到错误。

    goto LABEL;    // Error 跳过初始化
    int j = 0;
LABEL:
    ;
    return 0;

解决

给case下加个{}作用域就没问题了。这样变量的生存期就只限于单个case标签。

#include <iostream>
int main()
{
    switch (0) {
    case 1:
    {
        int b = 1;
    } break;
    default:
    }
    return 0;
}

下面的代码是能够正常编译的。

#include <iostream>
int main()
{
    switch (0) {
    case 1:
        int b; // 定义,没有初始化。
        break;
    default:
        b = 1;
        std::cout << b;
    }
    return 0;
}

//
#include <iostream>
int main()
{
    switch (0) {
    case 1:
        int b; // POD类型定义,没有初始化。
        b = 1; // 这里不会执行
        break;
    default:
        b = 1; // b赋值为1
        std::cout << b << std::endl;
        break;
    }
    return 0;
}

C++文档中指出

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer.

大致意思是,如果一个程序执行过程中,从A点跳到B点,中间有变量定义时候进行初始化,也就是跳过了具有自动存储周期的变量的初始化是非法的操作。除非变量具有POD类型,没有初始化器。

所以上面符合规则,是可以编译的。

POD

POD 是 Plain Old Data 的缩写。普通类型。两个系统进行交换数据,如果没有办法对数据进行语义检查和解释,那就只能以非常底层的数据形式进行交互,而拥有 POD 特征的类或者结构体通过二进制拷贝后依然能保持数据结构不变。

可以用 is_pod::value​ 来判断是不是POD类型。

  • 内存布局有序,成员是public,并且没有基类,没有构造、析构函数和虚函数。

  • 静态成员在这些规则下也是。

  • int, char, wchar_t, bool, float, double是POD类型,这些类型的long/short and signed/unsigned版本也是;

    • trivially copyable types (C style structs should all be trivially copyable)
  • enums枚举类型;

  • 指针(包括函数指针和成员指针)都是POD类型;

posted @ 2023-10-03 19:32  天空之城00  阅读(90)  评论(0)    收藏  举报