代码之家  ›  专栏  ›  技术社区  ›  HolyBlackCat

跳过变量初始化是否格式错误或导致UB?

  •  5
  • HolyBlackCat  · 技术社区  · 5 年前

    考虑以下代码:

    void foo()
    {
        goto bar;
        int x = 0;
        bar: ;
    }
    

    GCC和Clang reject it ,因为跳到 bar: 绕过变量初始化。MSVC根本不抱怨(除了使用 x 之后 酒吧: 引起警告)。

    我们可以用一个 switch :

    void foo()
    {
        switch (0)
        {
            int x = 0;
            case 0: ;
        }
    }
    

    现在,所有三个编译器 emit errors .

    这些片段是格式错误的吗?或者它们会导致UB吗?

    我过去认为这两个标准都不完善,但我找不到标准中有意义的部分。 [stmt.goto] 对此什么也没说,也没有 [stmt.select] .

    2 回复  |  直到 5 年前
        1
  •  20
  •   StoryTeller - Unslander Monica    5 年前

    当初始化为非空时,它的格式不正确。

    [stmt.dcl]

    3 可以转移到一个块中,但不能以这种方式 通过初始化绕过声明(包括 条件和init语句)。从一个点跳转的程序 其中具有自动存储持续时间的变量不在 除非变量具有 空初始化([basic.life])。在这种情况下,变量 使用空初始化时,按照它们的顺序构造 宣言。

    初始化器使初始化非空。相比之下,这

    void foo()
    {
        goto bar;
        int x; // no initializer
        bar: ;
    }
    

    将形成良好。尽管使用时通常需要注意 x 如果值不确定,则适用。

        2
  •  4
  •   Peter Mortensen icecrime    5 年前

    goto statement :

    如果控制权转移进入任何自动变量的范围 (例如,通过跳过声明语句),程序是 格式错误(无法编译),除非其作用域为 已输入

    1. 声明的标量类型没有初始化器
    2. 声明了平凡默认构造函数和平凡析构函数的类类型 没有初始化器
    3. 上述内容之一的简历合格版本
    4. 上述之一的数组