为什么第一个注释行正确编译,而第二个没有?
为什么a
可以作为构造函数参数给出,但b
可以'}
Aren这两个人做同样的事情吗?
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;
}
答案 0 :(得分:4)
在你的第一个代码中,两个声明都应该编译。海湾合作委员会就在那里。 Visual C ++编译器有bug。
在第二个代码中,内部声明应该不编译。 GCC也就在那里,VC ++也错了。
GCC在两种情况下都是正确的。
从语法的角度来看,像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类型的变量不会静态初始化。
有关静态初始化与动态初始化的更多详细说明,请参阅:
答案 1 :(得分:1)
在您的第一个示例中,正如您所注意到的,即使语法正常,行为也是未定义的。因此,允许编译器拒绝代码(但必须保证未定义的行为;它在这里,但如果从未实际执行过无效的初始化,则不会这样。)
您的第二个示例有一个类型错误:声明在看到声明符后立即可见,特别是它在自己的初始值设定项中可见。 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); }
^