令人惊讶的struct初始化 [英] Surprising struct initialization

查看:77
本文介绍了令人惊讶的struct初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想你永远不会完全了解C ++。我原本不会猜到

这实际上是编译和工作的:


struct Point {int x,y; };


struct line

{

点端点[2];

int weight;

};


行createLine(int sx,int sy,int ex,int ey)

{

行l = {sx,sy,ex,ey,1};

返回l;

}


gcc和Visual Studio 2005都很愉快地编译。


我的问题是:这是*真的*正确,还是两个编译器

只是宽松?初始化

块结构的确切规则是什么?

解决方案

Juha Nieminen写道:
< blockquote class =post_quotes>
我想你永远不会完全了解C ++。我原本不会猜到

这实际上是编译和工作的:


struct Point {int x,y; };


struct line

{

点端点[2];

int weight;

};


行createLine(int sx,int sy,int ex,int ey)

{

行l = {sx,sy,ex,ey,1};

返回l;

}


gcc和Visual Studio 2005都很愉快地编译。


我的问题是:这是*真的*正确,还是两个编译器

只是宽松?初始化

结构块的确切规则是什么?



IIRC,如果结构(或滥用类)是POD,您可以使用经典C表示法汇总其

结构。 POD是Plain Ole''数据 - 没有虚拟,

常量等.POD具有实现定义的内存布局 - 并且严格

自上而下的成员位置 - 所以{,,,}可以毫不含糊地利用这个来b / b
将数据丢入每个插槽。


-

Phlip


Juha Nieminen< no **** @ thanks.invalidkirjutas:


我想你永远不会完全了解C ++。我原本不会猜到

这实际上是编译和工作的:


struct Point {int x,y; };


struct line

{

点端点[2];

int weight;

};


行createLine(int sx,int sy,int ex,int ey)

{

行l = {sx,sy,ex,ey,1};

返回l;

}



这是使用C ++的C子集,用于数据对象和初始化,并且完全没问题。但是只需添加一个ctor到

Point或Line就可以使它们成为非POD并且初始化将是

非法。


AFAIK下一个C ++标准将放宽对PODness的一些约束,并且

添加一些语法以方便初始化正版C ++类,因为

井。


Paavo


7月3日9:05 * am,Juha Nieminen< nos ... @ thanks.invalidwrote:


struct Point {int x,y; };


struct line

{

* *点终点[2];

* * int weight;

};


行createLine(int sx,int sy,int ex,int ey)

{

* *行l = {sx,sy,ex,ey,1};

* *返回l;

}


* gcc和Visual Studio 2005都很愉快地编译。


*我的问题是:这是*真的*正确,还是两个编译器

只是宽大吗?初始化

结构块的确切规则是什么?



编译器不宽松 - 多个括号可以在
汇总初始化器中省略。因此,一个程序可以取代它:


行l = {{{sx,sy},{ex,ey}},1};


with:


线l = {sx,sy,ex,ey,1};


只要有足够的匹配聚合成员的参数。

否则,需要大括号。例如:


行l = {{{sx,xy}},1}; // l.endpoint [1]初始化为{0,

0}


我会在聚合初始化器中留下大括号(即使不是

需要)只是为了让代码更具可读性。


格雷格


I suppose you can never know C++ fully. I would have never guessed
this actually compiles and works:

struct Point { int x, y; };

struct Line
{
Point endpoint[2];
int weight;
};

Line createLine(int sx, int sy, int ex, int ey)
{
Line l = { sx, sy, ex, ey, 1 };
return l;
}

Both gcc and Visual Studio 2005 compile that happily.

My question would be: Is that *really* correct, or are both compilers
simply being lenient? What are the exact rules for the initialization
blocks of structs?

解决方案

Juha Nieminen wrote:

I suppose you can never know C++ fully. I would have never guessed
this actually compiles and works:

struct Point { int x, y; };

struct Line
{
Point endpoint[2];
int weight;
};

Line createLine(int sx, int sy, int ex, int ey)
{
Line l = { sx, sy, ex, ey, 1 };
return l;
}

Both gcc and Visual Studio 2005 compile that happily.

My question would be: Is that *really* correct, or are both compilers
simply being lenient? What are the exact rules for the initialization
blocks of structs?

IIRC, if a struct (or an abused class) is a POD, you can aggregate its
construction using classic C notation. POD is Plain Ole'' Data - no virtuals,
constants, etc. A POD has an implementation-defined memory layout - and strict
top-to-bottom member locations - so the {,,,} can exploit this to unambiguously
drop data into each slot.

--
Phlip


Juha Nieminen <no****@thanks.invalidkirjutas:

I suppose you can never know C++ fully. I would have never guessed
this actually compiles and works:

struct Point { int x, y; };

struct Line
{
Point endpoint[2];
int weight;
};

Line createLine(int sx, int sy, int ex, int ey)
{
Line l = { sx, sy, ex, ey, 1 };
return l;
}

This is using the C subset of C++, for both data objects and
initialization, and is perfectly fine as it is. But just add a ctor to
Point or Line to make them non-POD and the initialization would be
illegal.

AFAIK the next C++ standard will relax some constraints for PODness and
add some syntax for convenient initialization of genuine C++ classes as
well.

Paavo


On Jul 3, 9:05*am, Juha Nieminen <nos...@thanks.invalidwrote:

struct Point { int x, y; };

struct Line
{
* * Point endpoint[2];
* * int weight;
};

Line createLine(int sx, int sy, int ex, int ey)
{
* * Line l = { sx, sy, ex, ey, 1 };
* * return l;
}

* Both gcc and Visual Studio 2005 compile that happily.

* My question would be: Is that *really* correct, or are both compilers
simply being lenient? What are the exact rules for the initialization
blocks of structs?

The compilers are not being lenient - multiple braces can be elided in
an aggregate initializer. Therefore, a program can replace this:

Line l = {{{sx, sy}, {ex, ey}}, 1 };

with:

Line l = {sx, sy, ex, ey, 1 };

as long as there are enough arguments to match the aggregate members.
Otherwise, the braces would be needed. For example:

Line l = {{{sx, xy}}, 1}; // l.endpoint[1] is initialized to {0,
0}

I would leave the braces in an aggregate initializer (even when not
needed) just to make the code more readable.

Greg


这篇关于令人惊讶的struct初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆