gpt4 book ai didi

c++ - 表面上等效的表达式 (class)A a; 和 (class)A a{}; 之间的区别

转载 作者:行者123 更新时间:2023-11-30 04:45:56 25 4
gpt4 key购买 nike

我想知道,两者之间可能存在的内在差异是什么?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。所以对于aextern_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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com