下面的代码可以在g++和Visual C++编译器下都通过编译。为什么它是合法的?它看起来不合理,并且可能导致隐藏的错误。
int main() {
int i = i;
}
下面的代码可以在g++和Visual C++编译器下都通过编译。为什么它是合法的?它看起来不合理,并且可能导致隐藏的错误。
int main() {
int i = i;
}
x
会导致未定义的行为。i
。[...]如果对象未初始化,则需要进行此转换的程序具有未定义的行为。
i
等。 - James Kanzei
时它不是未初始化的,否则我认为关于这种情况标准所说的内容没有太多争议。 - Steve Jessop语法允许它的原因是,有一些奇怪的情况下,您可能想在变量的初始化器中使用指针或引用来使用它自己:
struct ThingManager {
void *thing;
ThingManager(void *thing) : thing(thing) {}
void Speak() {
if (thing == (void*)this) {
std::cout << "I'm managing myself\n";
} else {
std::cout << "I'm managing " << thing << "\n";
}
}
};
ThingManager self_manager(&self_manager);
ThingManager other_manager(&self_manager);
在C++中,你可以在对象的初始化表达式中引用它自己(它的名称在作用域中)。但是像往常一样,在C++中,你需要确保不会实际使用未初始化的值(例如int i = i;
中使用了未初始化的值)。
你的编译器可能会帮助识别未初始化值的使用情况,但标准不要求这样做。
-Winit-self
(与-Wuninitialized
一起使用)来让g++
警告您此用例。如果您将警告视为错误,它应该可以满足您的需求。0
,但在构造函数执行之前就已经使用了对象,则可能需要这样做。作为对C的回归,全局在程序启动时初始化为0
,然后C++运行时开始执行全局构造函数。对于那些定义的构造函数仅将对象初始化为0
的特定情况,自初始化不会造成任何伤害。i
是main
中的本地变量,因此未初始化。读取未初始化变量的结果始终是未定义的行为。
int i
(ii)i = i
。 - Salman Aint i;
而从未对i
进行分配的原因相同,这是合法的。 - asmeureri
是非法的。 - Luchian Grigore