我看到了很多关于这是否是定义行为的相互矛盾的信息。
struct C {
int m = 1;
int f() { return 2; }
};
C c;
std::string s;
int i;
std::cout << c.m;
std::cout << c.f();
std::cout << s;
std::cout << i;
我可以看到,如果声明
m
时没有赋值,结果会大不相同。同样对于枚举类型 E,E e; std::cout << e
未定义。
但是这里的输出是一致的
120
。事实上,您需要一个默认构造函数来声明 C c;
,这让我相信至少它可靠地等同于 C c = C();
。对于字符串来说应该没有什么不同,尽管在这种情况下我知道我已经看到它被称为未定义的行为。不知道 int。
如果你有:
struct C {
int m;
int f() { return 2; }
};
然后你创建一个实例并尝试访问变量m,根据ANSI规范,程序的行为是未定义的。 大多数情况下,m 的值将是垃圾值。 但是,如果它被声明为静态,它将自动初始化为 0。
您的帖子中的问题太多了(应该每个问题一个问题),所以我将重点关注您要说的内容
C
。
鉴于此:
struct C {
int m = 1;
int f() { return 2; }
};
每当您创建 m
类型的对象时,
1
都会被初始化(到 C
),所以:
C c;
std::cout << c.m;
非常好(并且会打印
1
)。
但是如果你有:
struct C {
int m;
int f() { return 2; }
};
那就是另一个故事了。
C c;
std::cout << c.m;
是未定义的行为,因为
m
未初始化。因此,第一个版本几乎总是首选,因为它消除了潜在错误的根源。
至于你的输出始终如一
120
:
std::string
的默认构造函数构造一个空字符串,因此 std::cout << s;
没问题(并且不打印任何内容)。
std::cout << i;
又是未定义的行为,并且恰好打印了 0
。但它可以做任何事情。