Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > C vs. C++: non-trivial designated initializers not supported

Reply
Thread Tools

C vs. C++: non-trivial designated initializers not supported

 
 
Johannes Bauer
Guest
Posts: n/a
 
      07-29-2010
Hello group,

I know this might be an implementation detail - however I do not
understand why the languages C++ and C are different in the following
example - I'm quite stunned and am looking for an explanation. Writing
some code and porting from C to C++ I encountered the error "sorry,
unimplemented: non-trivial designated initializers not supported" from
g++ 4.3.4. I boiled it down to a minimal example which compiles fine
under C, but emits that error message when compiled under C++:

typedef void (*FunctionType)(void);

typedef struct PODObject {
void *PointerValue;
FunctionType FunctionValue;
} PODObject;

void MyFunctionImpl(void);

PODObject vectorTable = {
FunctionValue: MyFunctionImpl,
};

void MyFunctionImpl() {
}


I have three options to make the code compile even when using C++:
1. Comment out the void* declaration of the PODObject
2. Change the order or PointerValue and FunctionValue
3. Define PointerValue in the struct definition

However, none of these options are really applicable in this particular
case. Is there a possibility or workaround or completely different
approach which lets me do the same thing as C does (i.e. fill the
undefined struct values with some random undefined data)?

Regards,
Johannes

--
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?

> Zumindest nicht öffentlich!

Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$(E-Mail Removed)>
 
Reply With Quote
 
 
 
 
Richard
Guest
Posts: n/a
 
      07-29-2010
[Please do not mail me a copy of your followup]

Johannes Bauer <(E-Mail Removed)> spake the secret code
<(E-Mail Removed)> thusly:

>PODObject vectorTable = {
> FunctionValue: MyFunctionImpl,
>};


I don't know what this is, but its not syntactically valid C or C++.
--
"The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download
<http://legalizeadulthood.wordpress.com/the-direct3d-graphics-pipeline/>

Legalize Adulthood! <http://legalizeadulthood.wordpress.com>
 
Reply With Quote
 
 
 
 
Jonathan Lee
Guest
Posts: n/a
 
      07-29-2010
On Jul 29, 12:57*pm, Johannes Bauer <(E-Mail Removed)> wrote:
> Hello group,
>
> I know this might be an implementation detail - however I do not
> understand why the languages C++ and C are different in the following
> example - I'm quite stunned and am looking for an explanation.


Designated initializers are a C99 feature, if I remember correctly.
Several features of C99 did not make it into the C++ specification.
I don't know if this particular one was rejected, never proposed,
planned, etc. It could have just been a matter of timing (since
the original C++ specification was 199.

I suspect, though, that the presence of constructors in C++
makes designated initializers mostly pointless.

> I have three options to make the code compile even when using C++:
> * 1. Comment out the void* declaration of the PODObject
> * 2. Change the order or PointerValue and FunctionValue
> * 3. Define PointerValue in the struct definition


Use #ifdef __cplusplus? It's ugly, but what do you expect
when mixing two different languages?

PODObject vectorTable = {
#ifdef __cplusplus
NULL, MyFunctionImpl
#else
FunctionValue: MyFunctionImpl
#endif
};


> However, none of these options are really applicable in this particular
> case. Is there a possibility or workaround or completely different
> approach which lets me do the same thing as C does (i.e. fill the
> undefined struct values with some random undefined data)?


Of course, if you dropped the requirement for uninitialized data
you could just fill in the first field with NULL. I highly doubt
it will create a performance hit...

--Jonathan
 
Reply With Quote
 
Johannes Bauer
Guest
Posts: n/a
 
      07-29-2010
Am 29.07.2010 19:08, schrieb Richard:
> [Please do not mail me a copy of your followup]
>
> Johannes Bauer <(E-Mail Removed)> spake the secret code
> <(E-Mail Removed)> thusly:
>
>> PODObject vectorTable = {
>> FunctionValue: MyFunctionImpl,
>> };

>
> I don't know what this is, but its not syntactically valid C or C++.


Are you sure? "gcc -Wall -Wextra -O2 -ansi -pedantic -c i.c" complains
only that it is an old form:

i.c:11: warning: obsolete use of designated initializer with ‘:’

However, it compiles, even with -ansi -pedantic. Therefore I doubt that
it's as far off the standard as your reply implies.

Regards,
Johannes

--
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?

> Zumindest nicht öffentlich!

Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$(E-Mail Removed)>
 
Reply With Quote
 
Johannes Bauer
Guest
Posts: n/a
 
      07-29-2010
Am 29.07.2010 19:11, schrieb Jonathan Lee:
> On Jul 29, 12:57 pm, Johannes Bauer <(E-Mail Removed)> wrote:
>> Hello group,
>>
>> I know this might be an implementation detail - however I do not
>> understand why the languages C++ and C are different in the following
>> example - I'm quite stunned and am looking for an explanation.

>
> Designated initializers are a C99 feature, if I remember correctly.
> Several features of C99 did not make it into the C++ specification.
> I don't know if this particular one was rejected, never proposed,
> planned, etc. It could have just been a matter of timing (since
> the original C++ specification was 199.


Hmm - actually it compiles with only a warning with -ansi -pedantic
-std=c89 (warning: obsolete use of designated initializer with ‘:’)

> Use #ifdef __cplusplus? It's ugly, but what do you expect
> when mixing two different languages?
>
> PODObject vectorTable = {
> #ifdef __cplusplus
> NULL, MyFunctionImpl
> #else
> FunctionValue: MyFunctionImpl
> #endif
> };


Well, actually the point of it all was that not all fields need to be
specified. The actual vectorTable contains >150 entries of which only
about 10 will be filled usually. The point of the whole construct was so
the unused fields can be omitted.

>> However, none of these options are really applicable in this particular
>> case. Is there a possibility or workaround or completely different
>> approach which lets me do the same thing as C does (i.e. fill the
>> undefined struct values with some random undefined data)?

>
> Of course, if you dropped the requirement for uninitialized data
> you could just fill in the first field with NULL. I highly doubt
> it will create a performance hit...


No, initialized data is fine (viewing initialized data as a subset of
uninitialized data). Anything which was omitted may well be set to 0 or
0xffffffff or whatever the compiler likes - if it only would allow me to
omit it (like the C compiler does).

Regards,
Johannes

--
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?

> Zumindest nicht öffentlich!

Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$(E-Mail Removed)>
 
Reply With Quote
 
Balog Pal
Guest
Posts: n/a
 
      07-29-2010
"Johannes Bauer" <(E-Mail Removed)>
> i.c:11: warning: obsolete use of designated initializer with ‘:’
>
> However, it compiles, even with -ansi -pedantic. Therefore I doubt that
> it's as far off the standard as your reply implies.


Designated init is definitely NOT in the C++ standard. The compiler emitted
a diagnostic for your ill-formed code, so it compiled the requirements, the
content of the message and what happens otherwise is a different issue.

More bad news: designated init is not in C++0x either. (Though there is
fairly enhanced {} init...)

If you want portable C++, do something else. If you're happy with what g++
does, it is an option too.

 
Reply With Quote
 
Johannes Bauer
Guest
Posts: n/a
 
      07-29-2010
Am 29.07.2010 19:31, schrieb Balog Pal:
> "Johannes Bauer" <(E-Mail Removed)>
>> i.c:11: warning: obsolete use of designated initializer with ‘:’
>>
>> However, it compiles, even with -ansi -pedantic. Therefore I doubt that
>> it's as far off the standard as your reply implies.

>
> Designated init is definitely NOT in the C++ standard. The compiler
> emitted a diagnostic for your ill-formed code, so it compiled the
> requirements, the content of the message and what happens otherwise is a
> different issue.


You read me wrong. The gcc C compiler compiles the code (even with
-std=c89) and emits a diagnostic.

The g++ C++ compiler does not compile the code at all. I'm just
wondering about this (since it is pretty basic stuff, putting a struct
somewhere and having it initialized with some values).

> More bad news: designated init is not in C++0x either. (Though there is
> fairly enhanced {} init...)
>
> If you want portable C++, do something else. If you're happy with what
> g++ does, it is an option too.


Well, g++ doesn't compile it - so that's not really an option. The most
interesting question you did not answer, however: How would you
formulate the requirement in portable C? C++0x is an option, I wouldn't
mind using C++0x features.

Regards,
Johannes

--
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt?

> Zumindest nicht öffentlich!

Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <hidbv3$om2$(E-Mail Removed)>
 
Reply With Quote
 
Jonathan Lee
Guest
Posts: n/a
 
      07-29-2010
On Jul 29, 1:20*pm, Johannes Bauer <(E-Mail Removed)> wrote:
> Well, actually the point of it all was that not all fields need to be
> specified. The actual vectorTable contains >150 entries of which only
> about 10 will be filled usually.


Ouch. Er... in that case I guess you'd have to declare the variable
without an initializer (or rely on zero initialization) and then set
them one by one.

I don't really have a better solution than that. (Other than, you know
140+ unused fields sounds like a struct that wants to be rewritten...)

--Jonathan
 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      07-29-2010
Johannes Bauer wrote:
>
> I know this might be an implementation detail - however I do not
> understand why the languages C++ and C are different in the following
> example - I'm quite stunned and am looking for an explanation.


C++ language does not have "designated initializers", neither trivial
nor non-trivial. The same applies to C89/90 version of C language. If
you only care to initialize one specific field with an aggregate
initializer, you have to supply _all_ initializers, beginning form the
first, until you reach the field in question. The rest of the
initializers can be omitted (meaning that the rest of the struct will be
implicitly zero-initialized).

>
> PODObject vectorTable = {
> FunctionValue: MyFunctionImpl,
> };


"Designated initializers" is a feature of C99 version of C language and
the proper syntax is as follows

PODObject vectorTable = { .FunctionValue = MyFunctionImpl };

> I have three options to make the code compile even when using C++:
> 1. Comment out the void* declaration of the PODObject


??? It is not clear what you mean here.

> 2. Change the order or PointerValue and FunctionValue


Well, as a way to make your code shorter, it will work (see below)

> 3. Define PointerValue in the struct definition


??? It is not clear what you mean here.

You have the 4th way: just do it the way it has been done for ages,
without any "designated initializers". Just supply all preceding
initializers explicitly

PODObject vectorTable = { 0, MyFunctionImpl };

Your 2nd approach is just a way to get rid of that explicit leading 0.

> However, none of these options are really applicable in this particular
> case. Is there a possibility or workaround or completely different
> approach which lets me do the same thing as C does (i.e. fill the
> undefined struct values with some random undefined data)?


"Undefined struct values" do not get filled with "random undefined
data". C language follows all-or-noting approach to initialization. If
you initialize just some of the struct fields (regardless of whether you
use designated initializers or not), the rest gets implicitly zero
initialized for you.

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      07-29-2010
Johannes Bauer wrote:
>
> Well, actually the point of it all was that not all fields need to be
> specified. The actual vectorTable contains >150 entries of which only
> about 10 will be filled usually. The point of the whole construct was so
> the unused fields can be omitted.


If this is a _maintenance_ issue, then the way to do it portably is to
define the struct object without any initializer at all and then use
_assignment_ to set some specific fields.

If this is a _performance_ issue, the initializers will not help you
here, since in C (and in similar context in C++), initializing just one
field of the struct automatically triggers zero-initialization for _all_
fields of the struct. I.e. if you want to leave all other fields
uninitialized (for performance reasons), the way to go is again to
define the struct object without any initializer at all and then use
assignment to set some specific fields.

> No, initialized data is fine (viewing initialized data as a subset of
> uninitialized data). Anything which was omitted may well be set to 0 or
> 0xffffffff or whatever the compiler likes - if it only would allow me to
> omit it (like the C compiler does).


Like _C99_ compiler does. If you want your code to be portable across
C89/90, C99 and C++ you have no other choice but to use either "no
initializer+assignment" approach or "supply all initializers beginning
from the first" approach.

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why Microsoft doesn't support designated initializers? ericnoonan C Programming 0 11-10-2009 07:56 AM
switches, spanning tree question regarding designated ports and switches alefveld@versatel.nl Cisco 1 12-30-2008 01:24 AM
A problem with designated initializers Ark C Programming 1 09-14-2006 05:41 AM
restrict from designated MAC address fangyong.F@gmail.com Cisco 0 01-12-2006 04:58 AM
Designated struct initializers with Visual C++ Roland Dreier C Programming 3 09-14-2003 09:45 AM



Advertisments