- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在 GCC 4.6.1 上,当我声明一个具有默认构造函数的我自己类型的实例时,如果我实例化一个该类型的对象并用大括号(如 Foo my_foo{}; )初始化它,POD 成员如果没有声明其他构造函数,则该类中的将仅进行零初始化。如果除了默认构造函数之外没有其他构造函数,它们将像预期的那样进行零初始化。
但是,在 GCC 4.7.3 上,零初始化以任何一种方式发生,这是我预期的行为。
这里有什么区别?这是编译器错误吗?这两个 GCC 版本都支持 C++11 标准的默认构造函数。
没有真正需要坚持使用旧的 GCC 版本,但我想了解这里发生了什么。
注意:我默认了主构造函数 op=。并复制 ctor 只是为了保持类型可用于可变参数函数(clang 要求将类归类为 POD,尽管 gcc 让我摆脱了使用具有可变参数函数的类型,即使是用户定义的主 ctor。奖励积分如果你能告诉我为什么。)
这里有一个示例程序来说明,包括底部的一些输出(来自使用两个 GCC 版本编译的二进制文件):
#include <cstdio>
// pod and pod_wctor are identical except that pod_wctor defines another ctor
struct pod {
pod( void ) = default;
pod( const pod& other ) = default;
pod& operator=( const pod& other ) = default;
int x,y,z;
};
struct pod_wctor {
pod_wctor( void ) = default;
pod_wctor( const int setx, const int sety, const int setz ) : x(setx), y(sety), z(setz) { }
pod_wctor( const pod_wctor& other ) = default;
pod_wctor& operator=( const pod_wctor& other ) = default;
int x,y,z;
};
int main ( void ) {
printf("the following shuold be uninitialized:\n");
pod pee;
printf( " %i,%i,%i\n", pee.x, pee.y, pee.z);
pod_wctor podtor;
printf( " %i,%i,%i\n", podtor.x, podtor.y, podtor.z);
printf("the following shuold be initialized to 0,0,0:\n");
pod peenit{};
printf( " %i,%i,%i\n", peenit.x, peenit.y, peenit.z );
pod_wctor podtornit{};
printf( " %i,%i,%i\n", podtornit.x, podtornit.y, podtornit.z );
return 0;
}
// compiled with: g++ m.cpp -std=gnu++0x
// g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 (i386)
/****************** output *******************
the following shuold be uninitialized:
10381592,134513249,134520820
134513969,134513504,0
the following shuold be initialized to 0,0,0:
0,0,0
7367877,134513945,8724468
*********************************************/
// compiled with: g++ m.cpp -std=gnu++0x
// gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-2ubuntu4) (i386)
/****************** output *******************
the following shuold be uninitialized:
-1218358300,-1217268232,134520832
134514450,1,-1079827548
the following shuold be initialized to 0,0,0:
0,0,0
0,0,0
*********************************************/
最佳答案
通过将构造函数 pod_wctor( const int setx, const int sety, const int setz ) : x(setx), y(sety), z(setz) { }
添加到您的类中,它失去聚合状态:[dcl.init.aggregate]/1
An aggregate is an array or a class (Clause 9) with no user-provided constructors
它仍然是一个 POD,因为一个普通类只需要没有非普通的默认 ctors:[class]/6
A trivial class is a class that has a default constructor (12.1), has no non-trivial default constructors, and is trivially copyable.
这里有趣的一点是,对于聚合,列表初始化 pod peenit{};
执行聚合初始化:
List-initialization of an object or reference of type
T
is defined as follows:
- If
T
is an aggregate, aggregate initialization is performed (8.5.1). [...]- Otherwise, if the initializer list has no elements and
T
is a class type with a default constructor, the object is value-initialized.
(注意:这是修改后的顺序。据我所知,在标准本身中,这两点的顺序是颠倒的,这一定是一个缺陷,因为每个聚合都有一个默认的构造函数——隐式声明和定义的构造函数。)
聚合初始化导致 int
成员的值初始化:[dcl.init.aggr]/7
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list
and [dcl.init.list]/3 "否则,如果初始化列表没有元素,则对象被值初始化"
但是,对于非聚合pod_wctor
,列表初始化pod_wctor podtornit{}
直接执行值初始化,调用默认的ctor。 [class.ctor]/6 指定:
The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.
在 [class.base.init]/8 中,我们发现:
In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then
- [...]
- otherwise, the entity is default-initialized (8.5).
默认构造函数本身不保证成员清零,因为它只对成员进行默认初始化。
默认初始化和值初始化的区别:[dcl.init]
[7] To default-initialize an object of type
T
means:
- if
T
is a (possibly cv-qualified) class type, the default constructor forT
is called [...]- [...]
- otherwise, no initialization is performed.
[...]
[8] To value-initialize an object of type
T
means:
- if
T
is a (possibly cv-qualified) class type with either no default constructor or a default constructor that is user-provided or deleted, then the object is default-initialized;- if
T
is a (possibly cv-qualified) non-union class type without a user-provided or deleted default constructor, then the object is zero-initialized and, ifT
has a non-trivial default constructor, default-initialized;- [...]
- otherwise, the object is zero-initialized.
(我承认这让我很困惑,我不得不修改我的答案。)
pod_wctor
有一个不是用户提供的默认构造函数。因此,对于列表初始化 pod_wctor podtornit{}
,value-initialization 的第二个项目符号适用。对象 podtornit
本身是零初始化,这导致其成员的零初始化。只有然后它才会被默认初始化,并且会调用默认的构造函数。后者什么也不做,但前者保证成员将被清零。
关于c++ - gcc 4.6 和 4.7 之间的默认构造函数差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18901315/
我从NVIDIA手册Eg中复制了以下代码:__threadfence()。他们为什么有 在以下代码中使用了__threadfence()。我认为使用__syncthreads()而不是__thread
我在使用 SVN 更改列表和 svn diff 时遇到了一些麻烦.特别是我想获取特定修订范围的特定文件列表的更改历史记录。 SVN 变更列表似乎是完美的解决方案,所以我的方法是: svn change
我有两个 IP 地址列表。我需要将它们合并到三个文件中,交集,仅来自 list1 的文件和仅来自 list2 的文件。 我可以用 awk/diff 或任何其他简单的 unix 命令来做到这一点吗?如何
假设自上次更新(恢复)到我的 a.b 文件以来我做了一些更改。 此 a.b 文件也在存储库中更改。 现在我想将我所做的更改与 repos 更改进行比较。 如果我 svn revert 文件,我可以看到
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我使用的是 openssl 1.0.1c , linux x86_64 我正在创建包含“hello”的文件(没有换行符) openssl dgst -sha256 hello_file i get :
假设我们有几个库。 有什么区别核心和 普通 图书馆?他们应该如何被认可,我们是否组织了两者的职责? +Common -Class1 +Core -Class2 +Lib1 has : Comm
如何在 SQLite 中计算以毫秒为单位的最小时间间隔? 好的,提供一些背景信息, 这是我的 table 的样子: link_budget table 所以有这个时间列,我想发出一个请求,以毫秒为单位
我想知道,乐观并发控制 (OCC) 和多版本并发控制 (MVCC) 之间的区别是什么? 到目前为止,我知道两者都是基于更新的版本检查。 在 OCC 中,我读到了没有获取读取访问锁的事务,仅适用于以后的
说到 SignalR,我有点菜鸟。刚刚开始四处探索和谷歌搜索它,我想知道是否有人可以向我解释完成的事情之间的一些差异。 在我见过的一些示例中,人们需要创建一个 Startup 类并定义 app.Map
我在 Ogre 工作,但这是一个一般的四元数问题。 我有一个对象,我最初对其应用旋转四元数 Q1。后来,我想让它看起来好像我最初通过不同的四元数 Q2 旋转了对象。 我如何计算四元数,该四元数将采用已
我了解 javascript 模块模式,但我使用两种类型的模块模式,并且想从架构 Angular 了解它们之间的区别。 // PATTERN ONE var module = (function()
我有两个具有完全相同键的 JSON。 val json1 = """{ 'name': 'Henry', 'age' : 26, 'activities' : {
我发现使用 VBA 在 Excel 中复制单个文件有两种不同的方法。一是文件复制: FileCopy (originalPath), (pathToCopyTo) 另一个是名称: Name (orig
我想知道查找两个 float 组之间差异的绝对值的最有效方法是什么? 是否是以下内容: private float absDifference(float[] vector1, float[] vec
我有一个关于 wicket getApplication 的问题。 getApplication() 和 getSession().getApplication 有什么区别? 部署 wicket 应用
我刚刚开始使用activemq,我有一个关于追溯消费者的问题,为了启用这个功能,你需要有一个持久的订阅。但是在主题上启用和不启用追溯的持久订阅有什么区别? activemq 文档说。 http://a
我有两个具有完全相同键的 JSON。 val json1 = """{ 'name': 'Henry', 'age' : 26, 'activities' : {
得到另一个 Erlang 二进制表示查询('因为这就是我最近正在阅读的内容,并且需要二进制协议(protocol)实现)。 如果我正确理解了类型说明符,那么对于“浮点”类型值,8 字节表示似乎很好(这
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
我是一名优秀的程序员,十分优秀!