令人惊讶的struct初始化 [英] Surprising struct initialization
问题描述
我想你永远不会完全了解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屋!