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 ]
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
--
> (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.
--
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
> 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
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
--