繁体   English   中英

与显式初始化相比,了解C ++中的复制初始化

[英]Understanding copy-initialization in C++, compared to explicit initialization

为什么第一个注释行编译正确,而第二个注释行编译不正确?

为什么a本身可以作为构造函数参数而b却不能呢?
两者不是在做同一件事吗?

class Foo { Foo &operator =(Foo const &); /* Disable assignment */ };

int main()
{
    Foo a = a;  // OK
    Foo  b(b);  // error C2065: 'b' : undeclared identifier
}

更新资料

由于它似乎依赖于编译器,因此问题似乎比我想的还要严重。
所以我想问题的另一部分是,以下代码是否有效?

它在GCC中给出了一个错误,但是Visual C ++可以很好地执行它。

int main()
{
    int i = 0;
    { int *i(&i); }
    return i;
}

在您的第一个代码中,两个声明都应编译。 海湾合作委员会就在那里。 Visual C ++编译器存在错误。

而在第二个代码,内部声明应该编译。 GCC也在那里,而VC ++是错误的。

在这两种情况下,海湾合作委员会都是正确的

int a=a+100;这样的代码int a=a+100; int a(a+100); 语法角度来看很好。 它们可能会根据是在静态存储期限内创建还是在自动存储期限内调用未定义的行为。

int a = a + 100; //well-defined. a is initialized to 100
                 //a on RHS is statically initialized to 0
                 //then a on LHS is dynamically initialized to (0+100).
void f()
{
   int b = b + 100; //undefined-behavior. b on RHS is uninitialized

   int a = a + 50; //which `a` is on the RHS? previously declared one?
                   //No. `a` on RHS refers to the newly declared one.
                   //the part `int a` declares a variable, which hides 
                   //any symbol with same name declared in outer scope, 
                   //then `=a+50` is the initializer part.
                   //since a on RHS is uninitialized, it invokes UB
}

请阅读上面与每个声明相关的注释。

请注意,具有静态存储持续时间的变量在编译时会被静态初始化为零,如果它们已经使用了初始化程序,那么它们也会在运行时进行动态初始化。 但是具有自动存储持续时间的POD类型变量不会被静态初始化。

有关静态初始化与动态初始化的更多详细说明,请参见:

如您所注意到的,在第一个示例中,即使语法正常,行为也是未定义的。 因此,允许编译器拒绝代码(但是,必须保证未定义的行为;在这里,但是如果从未真正执行过无效的初始化,则不会这样)。

您的第二个示例有一个类型错误:一个声明在看到其声明符后即可见,尤其是在其自己的初始化器中可见。 MSVC ++延迟了可见性:这是该编译器中一个已知的不合格问题。 例如,使用EDG编译器(具有Microsoft模式):

$ ./cfe --strict x.c
"x.c", line 4: error: a value of type "int **" cannot be used to initialize an
          entity of type "int *"
      { int *i(&i); }
               ^

1 error detected in the compilation of "x.c".
$ ./cfe --microsoft x.c
"x.c", line 4: warning: variable "i" was declared but never referenced
      { int *i(&i); }
             ^

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM