C99 designated initializers in C++0x

1809 views
Skip to first unread message

Seungbeom Kim

unread,
Feb 18, 2009, 3:54:14 PM2/18/09
to
Hello group,

What is the status of C99 designated initializers in C++0x?
I looked in N2800 but couldn't find anything related to it,
and I also searched comp.std.c++ and comp.lang.c++.moderated
but couldn't find anything more recent than 2004.

I'm asking this because it is a very useful feature, even in C++,
especially because of C-compatible APIs that take structs.
For example, I see a lot of the following pattern:

struct timeval timeout;
timeout.tv_sec = 2;
timeout.tv_usec = 500000L;
// followed by select(..., &timeout)

It would be nice to be able to write

struct timeval timeout = { .tv_sec = 2, .tv_usec = 500000L };

which the C people can already do now. This is not only more concise
-- eliminating all the redundancy (the occurrences of the variable,
'timeout' here) without sacrificing any significant information
(the member names, 'tv_sec' and 'tv_usec' here) -- but also possibly
more efficient because the compiler can replace the assignments with
a statically initialized object, especially when the object is const,
and you can make the object const here.

We could, of course, write

struct timeval timeout = { 2, 500000L };

but you lose the member names here. This is problematic because:

(1) You may not remember the correct ordering of the members,
which you don't care anyway with a sequence of assignments.
This may not be very obvious with such a short struct, but it is
especially obvious with a struct with a large number of members,
such as 'struct addrinfo'.

struct addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_protocol = IPPROTO_TCP;

Here you care about only two of the eightish members, and you care
about the names of only the two. You don't want to write:

// Note: ai_family is the 2nd member, ai_protocol is the 4th.
struct addrinfo hints = {0, AF_INET, 0, IPPROTO_TCP, };

but it would be really nice to write:

struct addrinfo hints = { .ai_family = AF_INET,
.ai_protocol = IPPROTO_TCP };

(2) You may make a mistake in matching the struct type and the members
correctly, and the compiler cannot save you from this. For example,
you might mistakenly believe that that 'struct timeval' has 'tv_sec'
and 'tv_nsec' (as 'struct timespec' does) and write:

struct timeval timeout = { 2, 500000000L };

to mean 2.5 seconds. With the designated initializers, you'd write:

struct timeval timeout = { .tv_sec = 2, .tv_nsec = 500000L };

and the compiler would catch the error for you.

On the other hand, I don't see any incompatibilities this would cause
in C++0x (mainly because this is only an extension).

Therefore, I would love to see this feature included in C++0x.
If any of you know its status, please let me know. Thank you.

--
Seungbeom Kim

[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Douglas Gregor

unread,
Feb 19, 2009, 12:17:34 PM2/19/09
to
On Feb 18, 12:54 pm, Seungbeom Kim <musip...@bawi.org> wrote:
> What is the status of C99 designated initializers in C++0x?
> I looked in N2800 but couldn't find anything related to it,
> and I also searched comp.std.c++ and comp.lang.c++.moderated
> but couldn't find anything more recent than 2004.
>
[snip]

>
> Therefore, I would love to see this feature included in C++0x.
> If any of you know its status, please let me know. Thank you.

Designated initializers will not be in C++0x. It's too late to add new
features to C++0x.

I don't actually recall any discussion in the committee about adding
designated initializers to C++0x, but I see no technical reason why
they couldn't be added into a future revision of C++. There are some
interesting potential interactions with generalized initializer lists.
For example, what does

f({.x = 10, .y = 20})

mean when "f" is a set of overloaded functions, e.g.,

struct Point { int x, y, z; };
struct Rectangle { Point topLeft, bottomRight; };
void f(Point); // #1
void f(Rectangle); // #2

Here, we should "obviously" pick #1, because Rectangle doesn't have
fields named "x" or "y", but that's going to require some interesting
SFINAE-like rules.

So, while I don't see any technical *problems* with designated
initializers in C++, there are definitely issues that need to be
resolved, and we'll of course need an implementation and proposal once
C++0x has shipped :)

- Doug


--

Pedro Lamarão

unread,
Feb 19, 2009, 12:28:03 PM2/19/09
to
On 18 fev, 17:54, Seungbeom Kim <musip...@bawi.org> wrote:

> (1) You may not remember the correct ordering of the members,
> which you don't care anyway with a sequence of assignments.
> This may not be very obvious with such a short struct, but it is
> especially obvious with a struct with a large number of members,
> such as 'struct addrinfo'.

> (2) You may make a mistake in matching the struct type and the members


> correctly, and the compiler cannot save you from this. For example,
> you might mistakenly believe that that 'struct timeval' has 'tv_sec'
> and 'tv_nsec' (as 'struct timespec' does) and write:

For me, the significant problem here is that many structs available in
a POSIX/C system don't actually have the order of their members
specified.
Consider this text from POSIX:

<spec>

[TMR] [Option Start] The <time.h> header shall declare the structure
timespec, which has at least the following members:

time_t tv_sec Seconds.
long tv_nsec Nanoseconds.

</spec>

It is not possible to write a portable program that initializes and
object of this type with an initializer list.

I don't actually think the C++ language needs new mechanisms to solve
this problem, since it already has one: constructors.
Maybe we will see constructors for these structs in POSIX/C++.

--
P.

--

Seungbeom Kim

unread,
Feb 20, 2009, 1:01:40 AM2/20/09
to
Pedro Lamarão wrote:
>
> For me, the significant problem here is that many structs available in
> a POSIX/C system don't actually have the order of their members
> specified.
> Consider this text from POSIX:
>
> <spec>
>
> [TMR] [Option Start] The <time.h> header shall declare the structure
> timespec, which has at least the following members:
>
> time_t tv_sec Seconds.
> long tv_nsec Nanoseconds.
>
> </spec>
>
> It is not possible to write a portable program that initializes and
> object of this type with an initializer list.

This makes the problem even worse, and means that we have no other
option than to stick to the "declare first and assign later" method.

I do expect, however, that some C++ compilers will provide the feature
as an extension, for they have to provide it as a C compiler anyway
in many cases. (GCC maybe?)

>
> I don't actually think the C++ language needs new mechanisms to solve
> this problem, since it already has one: constructors.
> Maybe we will see constructors for these structs in POSIX/C++.

Is there a real thing called POSIX/C++, or did you mean it as a joke?
(I don't see a smiley.. :))

Anyhow, many of us programming in C++ need to use POSIX/C still.
It's a pity that we are charged a penalty just for using C++,
compared to using C, when C compatibility is one of the primary
design goals of C++.

--
Seungbeom Kim

Anthony Williams

unread,
Feb 20, 2009, 1:30:19 PM2/20/09
to
Seungbeom Kim <musi...@bawi.org> writes:

> Pedro Lamarão wrote:
>> I don't actually think the C++ language needs new mechanisms to solve
>> this problem, since it already has one: constructors.
>> Maybe we will see constructors for these structs in POSIX/C++.
>
> Is there a real thing called POSIX/C++, or did you mean it as a joke?
> (I don't see a smiley.. :))

There is a POSIX/C++ working group currently active, with the intent of
producing a binding of the POSIX facilities for C++0x.

Anthony
--
Author of C++ Concurrency in Action | http://www.manning.com/williams
just::thread C++0x thread library | http://www.stdthread.co.uk
Just Software Solutions Ltd | http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

Pavel Minaev

unread,
Feb 21, 2009, 4:16:46 AM2/21/09
to
On Feb 19, 10:01 pm, Seungbeom Kim <musip...@bawi.org> wrote:
> Is there a real thing called POSIX/C++, or did you mean it as a joke?

There is an IEEE WG for a POSIX C++ binding - "P1003.27 (C/PA)
Standard for Information Technology - POSIX(R) C++ Language Interfaces -
Binding for System Application Program Interface (API)". See the
following links for more details:

http://standards.ieee.org/announcements/PR_New_Lan_Standards.html
https://www.redhat.com/mailman/listinfo/posix-c++-wg


--

Reply all
Reply to author
Forward
0 new messages