Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

815 views
Skip to first unread message

Johannes Bauer

unread,
Jul 29, 2010, 12:57:58 PM7/29/10
to
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$1...@speranza.aioe.org>

Richard

unread,
Jul 29, 2010, 1:08:21 PM7/29/10
to
[Please do not mail me a copy of your followup]

Johannes Bauer <dfnson...@gmx.de> spake the secret code
<8bdq8o...@mid.dfncis.de> 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>

Jonathan Lee

unread,
Jul 29, 2010, 1:11:03 PM7/29/10
to
On Jul 29, 12:57 pm, Johannes Bauer <dfnsonfsdu...@gmx.de> 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 1998).

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

Johannes Bauer

unread,
Jul 29, 2010, 1:12:14 PM7/29/10
to
Am 29.07.2010 19:08, schrieb Richard:
> [Please do not mail me a copy of your followup]
>
> Johannes Bauer <dfnson...@gmx.de> spake the secret code
> <8bdq8o...@mid.dfncis.de> 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.

Johannes Bauer

unread,
Jul 29, 2010, 1:20:01 PM7/29/10
to
Am 29.07.2010 19:11, schrieb Jonathan Lee:
> On Jul 29, 12:57 pm, Johannes Bauer <dfnsonfsdu...@gmx.de> 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 1998).

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).

Balog Pal

unread,
Jul 29, 2010, 1:31:29 PM7/29/10
to
"Johannes Bauer" <dfnson...@gmx.de>

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

Johannes Bauer

unread,
Jul 29, 2010, 1:31:47 PM7/29/10
to
Am 29.07.2010 19:31, schrieb Balog Pal:
> "Johannes Bauer" <dfnson...@gmx.de>
>> 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.

Jonathan Lee

unread,
Jul 29, 2010, 1:38:49 PM7/29/10
to
On Jul 29, 1:20 pm, Johannes Bauer <dfnsonfsdu...@gmx.de> 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

Andrey Tarasevich

unread,
Jul 29, 2010, 1:45:27 PM7/29/10
to
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

Andrey Tarasevich

unread,
Jul 29, 2010, 1:53:24 PM7/29/10
to
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.

Richard

unread,
Jul 29, 2010, 2:28:50 PM7/29/10
to
[Please do not mail me a copy of your followup]

Johannes Bauer <dfnson...@gmx.de> spake the secret code

<8bdr3e...@mid.dfncis.de> thusly:

>Am 29.07.2010 19:08, schrieb Richard:
>> [Please do not mail me a copy of your followup]
>>
>> Johannes Bauer <dfnson...@gmx.de> spake the secret code
>> <8bdq8o...@mid.dfncis.de> thusly:
>>
>>> PODObject vectorTable = {
>>> FunctionValue: MyFunctionImpl,
>>> };
>>
>> I don't know what this is, but its not syntactically valid C or C++.
>
>Are you sure?

No. That's why I said I don't know what it is. To me it looks like a
label declaration in the middle of an aggregate initializer, which is
why I didn't think it was syntactically valid C or C++.

I didn't know about designated initializers in C99. I have been using
C++ since 1990 and haven't been following C standardization beyond
that time.

So, it turns out that for (some flavors) of C, its syntactically
valid. However, I don't see anything that indicates its ever
syntactically valid C++.

At any rate, I don't see the value added here.

From looking at other posts and [1], even the syntax used here is
wrong. So its not even syntactically valid C99.

[1]
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/designators.htm

James Kanze

unread,
Jul 29, 2010, 2:39:32 PM7/29/10
to
On Jul 29, 6:08 pm, legalize+jee...@mail.xmission.com (Richard) wrote:

> Johannes Bauer <dfnsonfsdu...@gmx.de> spake the secret code
> <8bdq8oFns...@mid.dfncis.de> thusly:

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

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

It's valid C99. C++ is based on C90 (but the next version
didn't adopt this from C either---I don't know why not).

--
James Kanze

Richard

unread,
Jul 29, 2010, 2:56:53 PM7/29/10
to
[Please do not mail me a copy of your followup]

James Kanze <james...@gmail.com> spake the secret code
<54fc6600-1c5e-4dd6...@u26g2000yqu.googlegroups.com> thusly:

>> >PODObject vectorTable = {
>> > FunctionValue: MyFunctionImpl,
>> >};
>
>> I don't know what this is, but its not syntactically valid C or C++.
>
>It's valid C99.

Apparently not. The syntax is .member = initializer, not
member: initializer.

Johannes Bauer

unread,
Jul 29, 2010, 4:46:15 PM7/29/10
to
Am 29.07.2010 19:53, schrieb Andrey Tarasevich:
> 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.

This is not possible. The code is part of a IVT and therefore needs to
be laid out by the compiler to contain the function addresses of the ISRs.

> 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, see above.

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

Well, that's no real nice solution. The struct has around 150 actual ISR
handlers and I want to set some specific ones without having to know
where they all need to be placed in memory.

Johannes Bauer

unread,
Jul 29, 2010, 4:47:53 PM7/29/10
to

:-/

That seems to suck, is there really no other way? I cannot change the
initializers at runtime as the struct needs to be laid out in advance
and is placed in ROM (actually Flash, but ROM for that purpose).

Maybe I'll just use C-code for that part (with the correct ".foo = bar"
syntax of course) and mix the two languages. I'd really like to have
done it all in C++, though.

Johannes Bauer

unread,
Jul 29, 2010, 4:50:39 PM7/29/10
to
Am 29.07.2010 20:56, schrieb Richard:
> [Please do not mail me a copy of your followup]
>
> James Kanze <james...@gmail.com> spake the secret code
> <54fc6600-1c5e-4dd6...@u26g2000yqu.googlegroups.com> thusly:
>
>>>> PODObject vectorTable = {
>>>> FunctionValue: MyFunctionImpl,
>>>> };
>>
>>> I don't know what this is, but its not syntactically valid C or C++.
>>
>> It's valid C99.
>
> Apparently not. The syntax is .member = initializer, not
> member: initializer.

Yes, I used the deprecated variant. Is there anything like this in C++?

Kind regards,

Johannes Bauer

unread,
Jul 29, 2010, 4:54:00 PM7/29/10
to
Am 29.07.2010 19:45, schrieb Andrey Tarasevich:
> 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.

When I leave out the member "PointerValue" from the struct, it works
(since all are initialized then).

>> 2. Change the order or PointerValue and FunctionValue
>
> Well, as a way to make your code shorter, it will work (see below)

Well, it's not possible to change the order in my case (since the layout
of the struct is determined by hardware, not by me).

>> 3. Define PointerValue in the struct definition
>
> ??? It is not clear what you mean here.

If I define PointerValue, like say to 0...

> 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 };

...like you did here, then it also works. However, I really do not want
to have to use NULL 140 times and know exactly at what positions I need
to fill the proper ISR function pointers.

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

What I meant was: It could even be filled with random data. I do not
rely on it being initialized to anything, as the data is never read
during runtime.

Jonathan Lee

unread,
Jul 29, 2010, 5:14:09 PM7/29/10
to
On Jul 29, 4:47 pm, Johannes Bauer <dfnsonfsdu...@gmx.de> wrote:
> Am 29.07.2010 19:38, schrieb Jonathan Lee:
>
> > 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.
>
> :-/
>
> That seems to suck, is there really no other way? I cannot change the
> initializers at runtime as the struct needs to be laid out in advance
> and is placed in ROM (actually Flash, but ROM for that purpose).

The only other thing I can think of is to simply do this stuff in C
source and build that part of the tree with the C compiler :/

--Jonathan

Francesco S. Carta

unread,
Jul 29, 2010, 5:48:17 PM7/29/10
to
Johannes Bauer <dfnson...@gmx.de>, on 29/07/2010 22:46:15, wrote:

> Am 29.07.2010 19:53, schrieb Andrey Tarasevich:
>> Johannes Bauer wrote:
>>> 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.
>
> Well, that's no real nice solution. The struct has around 150 actual ISR
> handlers and I want to set some specific ones without having to know
> where they all need to be placed in memory.

What is so ugly with the "no initialized + assignment" approach
suggested by Andrey?

This chunk of code isn't all that hard to type or to review, is valid
everywhere (within the context at hand) and, IIUIC, should also be
faster than the C99 version mentioned in the OP:

//-------
PODObject obj;
obj.FunctionValue = MyFunctionImpl;
//-------


And if one really wants a one-liner, one can always take advantage
(grin) of the preprocessor:

//-------
#define CREATEPOD(obj_name, member_name, value) \
PODObject obj_name; \
obj_name.member_name = value;

typedef void(*FunctionType)();

struct PODObject {
void* PointerValue;
FunctionType FunctionValue;

};

void MyFunctionImpl() {}

int main() {
CREATEPOD(obj, FunctionValue, MyFunctionImpl);
obj.FunctionValue();
}
//-------

For the records, I wouldn't use macros, I would just use the two lines I
mentioned first.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com

Balog Pal

unread,
Jul 29, 2010, 6:09:21 PM7/29/10
to
"Francesco S. Carta" <entu...@gmail.com>

>> Well, that's no real nice solution. The struct has around 150 actual ISR
>> handlers and I want to set some specific ones without having to know
>> where they all need to be placed in memory.
>
> What is so ugly with the "no initialized + assignment" approach suggested
> by Andrey?

As Johannes stated in the part you cut out, that stuff goes to a const
segment sitting in ROM, so assignment does not play, only static init.

The part I don't get is why providing initializer for all struct members
(either literally, or better yet using a macro) is so painful. Such tables
are routinely created using macros. (For those unfamiliar with embedded,
you start work by including a few hundred kByte header with half content
being #define... so using a few more hardly hurts ;-)


Francesco S. Carta

unread,
Jul 29, 2010, 6:07:36 PM7/29/10
to
Balog Pal <pa...@lib.hu>, on 30/07/2010 00:09:21, wrote:

> "Francesco S. Carta" <entu...@gmail.com>
>>> Well, that's no real nice solution. The struct has around 150 actual ISR
>>> handlers and I want to set some specific ones without having to know
>>> where they all need to be placed in memory.
>>
>> What is so ugly with the "no initialized + assignment" approach
>> suggested by Andrey?
>
> As Johannes stated in the part you cut out, that stuff goes to a const
> segment sitting in ROM, so assignment does not play, only static init.

Sorry, I overlooked that part.

Jorgen Grahn

unread,
Jul 30, 2010, 4:04:33 AM7/30/10
to
On Thu, 2010-07-29, Johannes Bauer wrote:
> Am 29.07.2010 20:56, schrieb Richard:
>> [Please do not mail me a copy of your followup]
>>
>> James Kanze <james...@gmail.com> spake the secret code
>> <54fc6600-1c5e-4dd6...@u26g2000yqu.googlegroups.com> thusly:
>>
>>>>> PODObject vectorTable = {
>>>>> FunctionValue: MyFunctionImpl,
>>>>> };
>>>
>>>> I don't know what this is, but its not syntactically valid C or C++.
>>>
>>> It's valid C99.
>>
>> Apparently not. The syntax is .member = initializer, not
>> member: initializer.
>
> Yes, I used the deprecated variant. Is there anything like this in C++?

The "deprecated variant" was, as far as I can tell a GCC extension to
the C language, not something that was ever part of the language. The
manual says it's obsolete since GCC 2.5 -- i.e. a really long time
ago.

I seem to recall the Linux kernel using 'FIELDNAME: value' at one point,
later switching to '.FIELDNAME = value'.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Johannes Bauer

unread,
Jul 30, 2010, 11:06:48 AM7/30/10
to
Am 30.07.2010 00:09, schrieb Balog Pal:

> The part I don't get is why providing initializer for all struct members
> (either literally, or better yet using a macro) is so painful.

Image you have 150 ISRs. You occupy only 3 of them, #17, #99 and #130.

This means you have to write

0, (16 times)
FirstISR,
0, (81 times)
SecondISR,
0, (30 times)
ThirdISR,
0, (20 times)

Calculating these numbers by oneself is incredibly error-prone. Even
worse: If you're off-by-one (as I actually was when I first wrote these
lines) you will not get any error, but it will rain crap during runtime.

It is much less error prone to write:

.USART_RXC = FirstISR,
.Ethernet_RXC = SecondISR,
.ExternalIRQ = ThirdISR

and not have to worry about the actual positions.

Furthermore, say you insert one beween #2 and #3 (say at 104). Then you
have to split the "0, (30 times)" up (into 4 + 25) which is even more
error-prone.

> Such
> tables are routinely created using macros. (For those unfamiliar
> with embedded, you start work by including a few hundred kByte header
> with half content being #define... so using a few more hardly hurts ;-)

If you knew a way to do this with macros, I'd be fine with it. However
nobody here has come up with a solution to make this problem work with
C++ (either using macros or not). I start to believe there may be no way
to solve that using C++ (which is IMHO, a pity, considering that C can
do it with ease).

Francesco S. Carta

unread,
Jul 30, 2010, 11:50:49 AM7/30/10
to

If plain source code size is not a problem, you can do:

PODObject pod = {
0, // #0 member name
0, // #1 member name
0, // #2 member name
// ...
0 // #149 member name
}

And set just what you need wherever you need it, in this way you can be
sure you won't mess up the list.

Otherwise, if you think you can get the number of intervening unused
members right, you can create macros like this:

#define Z_5 0, 0, 0, 0, 0
#define Z_10 Z_5, Z_5
#define Z_20 Z_10, Z_10
#define Z_25 Z_20, Z_5
#define Z_50 Z_25, Z_25
#define Z_100 Z_50, Z_50

and use them like this:

PODObject pod = {
Z_50, Z_20,
42,
Z_10, 0, 0,
78
}

I know, it's ugly and hard to maintain, but it's better than writing and
counting zeroes by hand, and personally I would really use the complete
(commented) initialization list I mentioned above, seen that I found no
better C++ solution in the context at hand.

Richard

unread,
Jul 30, 2010, 1:01:40 PM7/30/10
to
[Please do not mail me a copy of your followup]

Johannes Bauer <dfnson...@gmx.de> spake the secret code
<8bg84b...@mid.dfncis.de> thusly:

>If you knew a way to do this with macros, I'd be fine with it.

I don't understand the difficulty here. I'd write a macro that takes
the non-zero elements of the initializer and supplies all the zero
elements. Its really not that hard:

#define INITIALIZE(first_, second_, third_) \
{ \
first_, 0, 0, 0, 0, \
second_, 0, 0, 0, 0, \
third_ \
}

etc.

HugeStruct s = INITIALIZE(10, 20, 30);

I've done this before when initializing structs with huge initializer
lists; its really no big deal.

I believe that any unspecified initializers at the end of the list will
automatically be filled with zero, so there's no need to specify them
explicitly.

James Kanze

unread,
Jul 31, 2010, 8:18:21 AM7/31/10
to
On Jul 30, 4:06 pm, Johannes Bauer <dfnsonfsdu...@gmx.de> wrote:
> Am 30.07.2010 00:09, schrieb Balog Pal:

> > The part I don't get is why providing initializer for all struct members
> > (either literally, or better yet using a macro) is so painful.

> Image you have 150 ISRs. You occupy only 3 of them, #17, #99 and #130.

> This means you have to write

> 0, (16 times)
> FirstISR,
> 0, (81 times)
> SecondISR,
> 0, (30 times)
> ThirdISR,
> 0, (20 times)

> Calculating these numbers by oneself is incredibly
> error-prone. Even worse: If you're off-by-one (as I actually
> was when I first wrote these lines) you will not get any
> error, but it will rain crap during runtime.

While I do think that adding the designated initializer syntax
to C++ would have been useful, in this particular case, I don't
see any real problem. It would take less than ten minutes to
write a small script in AWK which generates the full initializer
list, given the structure definition (supposing it is formatted
according to some established convention) and a list of the
concerned elements with their initializer.

--
James Kanze

0 new messages