- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我试图确定 N3337 §8.5p7 (C++11) 和 N3797 §8.5p8(后 C++11)之间处理值初始化的差异。
N3337 §8.5p7:
To value-initialize an object of type T means:
- if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
- if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
- if T is an array type, then each element is value-initialized;
- otherwise, the object is zero-initialized.
An object that is value-initialized is deemed to be constructed and thus subject to provisions of this International Standard applying to “constructed” objects, objects “for which the constructor has completed,” etc., even if no constructor is invoked for the object’s initialization.
N3797 §8.5p8:
To value-initialize an object of type T means:
- if T is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a default constructor that is user-provided or deleted, then the object is default-initialized;
- if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;
- if T is an array type, then each element is value-initialized;
- otherwise, the object is zero-initialized.
An object that is value-initialized is deemed to be constructed and thus subject to provisions of this International Standard applying to “constructed” objects, objects “for which the constructor has completed,” etc., even if no constructor is invoked for the object’s initialization.
鉴于这两条规则,下面的代码片段应该会给出不同的结果:
#include <iostream>
struct Base {
int i;
Base(int i):i(i) {}
Base():i(10) {}
};
struct Derived : public Base {
int j;
Derived(int j):Base(j), j(j) {}
Derived()=default;
};
int main() {
Derived d{};
std::cout << "d.i = " << d.i << " " << "d.j = " << d.j << '\n';
}
如下:
Derived
的默认构造函数,因为 Derived
具有用户提供的构造函数。 Derived
的默认构造函数调用 Base
默认构造函数,它初始化 Derived::i = 10
,留下 Derived::j
单元化。Derived
没有用户提供的默认构造函数,也没有删除的默认构造函数,因此适用第二个要点。也就是说,Derived
是零初始化的,即 Derived::i
和 Derived::j
都是用 0 初始化的,对象 d
是默认初始化的,它留下 Derived::i = 10
。虽然我对 Unix 的了解很少,但我一直在尝试复制这两个案例,对编译器 clang++ 和 g++ 使用不同的标志,通过反复试验,在 Coliru 中,无济于事。到目前为止的结果,全部打印d.i = 10 d.j = 0
没有警告。
最佳答案
OP 中的程序无法区分 d.j
是否被初始化为 0,或者它是否未初始化且恰好为 0。如果要创建有问题的 Derived 对象,这将很清楚在已经初始化为已知非零值的内存中,比如放置新的:
Derived d{42}; // d.i and d.j are both 42.
::new (&d) Derived{}; // d.i is 0, d.j is 0 per N3797 or 42 per N3337.
作为dyp says in his comment ,编译器通常会跟踪由于标准中的缺陷(而不是新功能)引起的更改,并将它们包含在对特定标准修订版的支持中。鉴于标准不断变化,可能没有编译器可以完全编译任何给定标准文档中指定的语言。例如,当您告诉 clang 3.4 编译 C++11 时,它实际实现的语言是“C++11 的一部分加上我们为 3.4 版本及时实现的相关缺陷解决方案(IIRC 3.4 的所有部分)” ”
OP 询问的对值初始化 措辞的特定更改发生在 Core Working Group (CWG) Defect Report (DR) number 1301 的决议中。这也解决了DR1324和 DR1368 .作为缺陷解决方案,编译器随后将有理由实现更改。
各种编译器和版本的分析(主要由 OP 执行)表明:
总而言之,没有办法强制编译器完全按照指定的方式执行,但我们通常可以通过一些仔细的分析来确定到底发生了什么。
关于c++ - 如何调用 clang++ 或 g++ 来准确复制两个不同标准版本中的需求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21023071/
我知道的引用资料在这里: http://clang.llvm.org/docs/ClangCommandLineReference.html http://clang.llvm.org/docs/Di
这两个工具似乎有一些共同的目标,而 documentation of clang-tidy对其功能非常明确,clang-check's有点稀疏。 如果我只能运行这些工具中的一个,同时进行相同的检查,那
我不清楚 clang 使用的汇编器。 AFAIK native 又名 GNU 汇编器和链接器被使用(与 gcc 一起提供)。 clang -v main.c clang version 3.4.2 T
在哪里可以找到 Clang 标志的完整列表? 还有一些,例如 -include-pch,甚至没有在手册页中列出。 :( 我知道 GCC 使用一些相同的标志,但它不包含诸如 -Os 之类的文档,我相信这
大多数成熟的编译器似乎对堆栈变量破坏有很好的支持。 海湾合作委员会:-fstack-protector xlC: -qstackprotect 英特尔:-fstackprotector window
我的命令: /usr/bin/c++ -fPIC -I/Users/me/project/include -I/usr/local/include/opencv \ -I/usr/local/incl
我正在研究 CLang 3.5。我正在尝试获取有关在 C++ 项目中声明的变量的信息。 如何获取 clang::VarDecl 中变量的数据类型或限定类名, clang::FieldDecl或 cla
我正在尝试构建 LLVM 编译器,以便我可以在 Apple M1 上启用 OpenMP。 我正在使用 LLVM 开发树,(因为我最近看到一些 OpenMP 运行时对此进行了处理)。 我已经结束了这个脚
背景: 在 Windows 10 PC 上,我有一个 C++ 代码库。使用 CMAKE 我生成了一个 Mingw-w64 项目(使用 Eclipse IDE)和一个 Visual Studio 201
下面是我想做的。 我想通过使用 cmake 的正确程序检测 clang 来使用 clang/clang++ 进行编译。 请告诉我可以解决我将描述的问题的正确程序。 test environment:
基本问题 我有以下代码 #include #include using namespace std; int main () { int32_t spam; spam=5; cout
当我在xcode中编译.c文件时,出现错误提示: clang error: argument unused during compilation: '-fno-objc-exceptions' [-W
Clang has several kinds of diagnostics ,其中三种主要是错误、警告和注释。 注释通常伴随着某些警告和错误,例如重复定义: error: conflicting t
我正在调整 Clang 工具模板(如 here 所述)以在我的代码中搜索特定的方法调用。为了稍后重写该调用,我想获取调用该方法的参数的类型,以及调用该方法的对象的类型。 我设法找到了一个可以回调以下内
我必须通过在它之前添加一个语句来检测 clang 中的某些语句。我有一个指向 Expr 对象的指针,我需要在包含它的语句之前插入另一个语句。现在我正在使用一种hacky方法,它只是将 SourceLo
类 clang::ASTContext 有一个方法: DynTypedNodeList getParents(const NodeT &Node) 它返回给定 AST 节点的父节点列表。 通常 AST
我想修改代码分析器程序clang-tidy的检查正在做,但是好像是配置文件.clang-tidy的内容正在被忽视。 我通过调用 clang-tidy 创建文件带旗-dump-config并将输出重定向
有没有办法用clang创建一个可以合理地适合页面的调用图? 即给出: #include using namespace std; int main() { int a; cin>>a;
我正在编写一个 Clang 工具,并且试图弄清楚如何在访问程序 AST 的情况下评估字符串文字。给定以下程序: class DHolder { public: DHolder(std::strin
我想在 Clang 中尝试一些新功能,有人提到我 Clang TOT . 现在这可能是一个明显的问题,到底是什么Clang TOT . TOT 一定是一些我不熟悉的首字母缩写词。 任何人都可以启发我吗
我是一名优秀的程序员,十分优秀!