- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道,两者之间可能存在的内在差异是什么?A a;
和 A a{};
(A 类,无构造函数)?
我只是在玩代码,发现了一些非常有趣的东西,将全局类实例声明为 A a;
与使用 A a{}; 相比产生了不同的结果;
代替。
这很有趣,因为我明白:
声明一个没有初始化的类实例会调用默认构造函数(没有参数的构造函数,如果存在的话)。
a{}
是一个创建类实例并调用默认构造函数的表达式。
所以,基本上是同一件事,但它们确实在特定条件下产生了不同的结果,尽管它是通过打破 ODR 在可能的 UB 领域中发现的。
我的问题是,如果 A a;
严格等同于 A a{};
?
从逻辑上讲,它们的内部实现之间应该存在一些差异以产生不同的结果,而其他一切都保持完全相同。我想知道这有什么区别。
我使用的是 Visual Studio 2017。
//extern_src.cpp
class A {
public:
int a=24;
};
A extern_a; // << here, if i put {} at the end, different results comes out;
//src.cpp
#include <iostream>
class A {
public:
int a=3;
};
int main() {
extern A extern_a;
A a;
std::cout << a.a << " " << extern_a.a << std::endl;
return 0;
}
没有 {}
,代码打印出 3 3
。所以对于a
和extern_a
,都会调用定义在src.cpp
中的类A的构造函数。
使用 {}
,代码打印出 3 24
。在这种情况下,为 extern_A
调用在 extern_src.cpp
中定义的构造函数。
默认构造函数似乎并没有立即被调用,而只是在第一种情况(没有 {}
的类实例声明)的编译过程中稍后调用。
我确实理解这是因为对单个类有多个定义而破坏了 ODR。但我的问题是,如果 A a;
完全等同于 A a{};
,因为它们都在调用默认构造函数,那么它们如何产生不同的结果?
最佳答案
您已经证明您的程序违反了单一定义规则。每[basic.def.odr]/12 :
There can be more than one definition of a class type [...] Given such an entity named
D
defined in more than one translation unit, then
each definition of
D
shall consist of the same sequence of tokens; and[...]
[...] If the definitions of
D
do not satisfy these requirements, then the behavior is undefined.
A
的定义不包含相同的标记序列,因此行为未定义。当行为未定义时,所有赌注都将取消。即使是同一个程序在再次编译时也会有不同的行为。并不是说 A a;
和 A a{};
是不同的语句(或者更准确地说,简单声明s,但不是表达式)。每[defns.undefined] :
undefined behavior
behavior for which this document imposes no requirements
[ Note: Undefined behavior may be expected when this document omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed. Evaluation of a constant expression never exhibits behavior explicitly specified as undefined in [intro] through [cpp] of this document ([expr.const]). — end note ]
另见 Undefined, unspecified and implementation-defined behavior了解未定义行为的可能后果。特别是,一个版本的 GCC (1.17) 在遇到某些未定义的行为时试图启动游戏 NetHack、Rogue 和 Towers of Hanoi。 [1]
关于c++ - 表面上等效的表达式 (class)A a; 和 (class)A a{}; 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57027783/
我是一名优秀的程序员,十分优秀!