Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #24186 > unrolled thread

Static array with #defined # of "extra" members

Started byIan Pilcher <arequipeno@gmail.com>
First post2012-08-03 21:05 -0500
Last post2012-08-04 16:19 +0200
Articles 6 — 5 participants

Back to article view | Back to comp.lang.c


Contents

  Static array with #defined # of "extra" members Ian Pilcher <arequipeno@gmail.com> - 2012-08-03 21:05 -0500
    Re: Static array with #defined # of "extra" members "China Blue [Tor], Meersburg" <chine.bleu@yahoo.com> - 2012-08-03 19:40 -0700
    Re: Static array with #defined # of "extra" members Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-03 22:43 -0400
      Re: Static array with #defined # of "extra" members Ian Pilcher <arequipeno@gmail.com> - 2012-08-04 10:00 -0500
    Re: Static array with #defined # of "extra" members Philip Lantz <prl@canterey.us> - 2012-08-03 16:46 -1000
    Re: Static array with #defined # of "extra" members Jens Gustedt <jens.gustedt@loria.fr> - 2012-08-04 16:19 +0200

#24186 — Static array with #defined # of "extra" members

FromIan Pilcher <arequipeno@gmail.com>
Date2012-08-03 21:05 -0500
SubjectStatic array with #defined # of "extra" members
Message-ID<Yr%Sr.76276$FV6.41256@newsfe05.iad>
I need to create a static array of structures with the following
characteristics:

* The first few members of the array are pre-initialized
* The remaining members of the array are initialized to "zero"
* The number of additional members is determined by a #defined constant,
  independently of the number of pre-initialized members

Here's what I've come up with:


#define NUM_EXTRA_FOOS     5

struct foo {
    int data;
};

static struct {
    struct foo builtin[5];
    struct foo extra[NUM_EXTRA_FOOS];
} all_foos = {
    { { 1 }, { 2 }, { 3 }, { 4 }, { 5 } },
    { { 0 } }
};

#define foos  all_foos.builtin

I believe that I can effectively use foos[] as an array with 10 (5 +
NUM_EXTRA_FOOS) elements.

* Is my belief correct?
* Is there any danger of the compiler inserting unwanted padding between
  the builtin and extra members of the anonymous struct?
* Is there a better way to do this?

Thanks!

-- 
========================================================================
Ian Pilcher                                         arequipeno@gmail.com
"If you're going to shift my paradigm ... at least buy me dinner first."
========================================================================

[toc] | [next] | [standalone]


#24187

From"China Blue [Tor], Meersburg" <chine.bleu@yahoo.com>
Date2012-08-03 19:40 -0700
Message-ID<chine.bleu-5B2030.19403203082012@news.eternal-september.org>
In reply to#24186
In article <Yr%Sr.76276$FV6.41256@newsfe05.iad>,
 Ian Pilcher <arequipeno@gmail.com> wrote:

> I need to create a static array of structures with the following
> characteristics:
> 
> * The first few members of the array are pre-initialized
> * The remaining members of the array are initialized to "zero"
> * The number of additional members is determined by a #defined constant,
>   independently of the number of pre-initialized members
> 
> Here's what I've come up with:
> 
> 
> #define NUM_EXTRA_FOOS     5
> 
> struct foo {
>     int data;
> };
> 
> static struct {
>     struct foo builtin[5];
>     struct foo extra[NUM_EXTRA_FOOS];
> } all_foos = {
>     { { 1 }, { 2 }, { 3 }, { 4 }, { 5 } },
>     { { 0 } }
> };
> 
> #define foos  all_foos.builtin
> 
> I believe that I can effectively use foos[] as an array with 10 (5 +
> NUM_EXTRA_FOOS) elements.
> 
> * Is my belief correct?

Probably, but not guaranteed universally true.

> * Is there any danger of the compiler inserting unwanted padding between
>   the builtin and extra members of the anonymous struct?

If you want to be implementation independent--yes, the hazard exists.

There is little danger that padding will be inserted, but making that assumption 
does constitute an implementation dependency.

> * Is there a better way to do this?

You can't do counted repetition (with either iteration or recursion) with C 
preprocessor. If you're trying to add NUM_EXTRA_FOOS zeros, I don't see a way to 
do it with cpp. If you want one zero if NUM_EXTRA_FOOS>0,

    static struct {
        struct foo builtin[5+NUM_EXTRA_FOOS];
                /* 5+NUM_EXTRA_FOOS is constant expression and folded */
    } all_foos = {
        { 1 }, { 2 }, { 3 }, { 4 }, { 5 },
        #if NUM_EXTRA_FOOS>0
            { 0 }
        #endif
    };

but uninitialised statics are zeroed out anyway.

You can do more advanced substitution with an alternative preprocessor like m4 
or some special purpose program you write.

-- 
My name Indigo Montoya.      |            Die, Robbie Ferrier! Die!
You flamed my father.        |       I'm whoever you want me to be.
Prepare to be spanked.       |  Annoying Usenet one post at a time.
Stop posting that!           |    At least I can stay in character.

[toc] | [prev] | [next] | [standalone]


#24188

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-08-03 22:43 -0400
Message-ID<jvi27t$log$1@dont-email.me>
In reply to#24186
On 8/3/2012 10:05 PM, Ian Pilcher wrote:
> I need to create a static array of structures with the following
> characteristics:
>
> * The first few members of the array are pre-initialized
> * The remaining members of the array are initialized to "zero"
> * The number of additional members is determined by a #defined constant,
>    independently of the number of pre-initialized members
>
> Here's what I've come up with:
>
>
> #define NUM_EXTRA_FOOS     5
>
> struct foo {
>      int data;
> };
>
> static struct {
>      struct foo builtin[5];
>      struct foo extra[NUM_EXTRA_FOOS];
> } all_foos = {
>      { { 1 }, { 2 }, { 3 }, { 4 }, { 5 } },
>      { { 0 } }
> };
>
> #define foos  all_foos.builtin
>
> I believe that I can effectively use foos[] as an array with 10 (5 +
> NUM_EXTRA_FOOS) elements.
>
> * Is my belief correct?

     The struct all_foos will be at least large enough for 10
elements, possibly larger if there's (perverse) padding.

     However, trying to use all_foos.builtin[5] might not work
(see "struct hack") and even if it works it is not necessarily
the case that &all_foos.builtin[4]+1 == &all_foos.extra[0].  You
need to use something like

	#define foos ((struct foo*)&all_foos)

> * Is there any danger of the compiler inserting unwanted padding between
>    the builtin and extra members of the anonymous struct?

     In principle, yes.  Padding can appear after any struct element,
even if the implementor's reasons for putting it there don't seem
convincing.

> * Is there a better way to do this?

     struct foo foos[5 + NUM_EXTRA_FOOS] =
         { {1}, {2}, {3}, {4}, {5} };

The compiler might warn about the incomplete initializer, but C
defines the effect: The extras are initialized to zero-value.  You
might be able to suppress the warning with a C99-style initializer:

     struct foo foos[5 + NUM_EXTRA_FOOS] =
	{ {1}, {2}, {3}, {4}, {5}, [5+NUM_EXTRA_FOOS-1] = {0} );

... or even

     struct foo foos[] =
	{ {1}, {2}, {3}, {4}, {5}, [5+NUM_EXTRA_FOOS-1] = {0} );

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#24209

FromIan Pilcher <arequipeno@gmail.com>
Date2012-08-04 10:00 -0500
Message-ID<WNaTr.7722$BI5.5599@newsfe09.iad>
In reply to#24188
On 08/03/2012 09:43 PM, Eric Sosman wrote:
> On 8/3/2012 10:05 PM, Ian Pilcher wrote:
>> * Is there a better way to do this?
> 
>     struct foo foos[5 + NUM_EXTRA_FOOS] =
>         { {1}, {2}, {3}, {4}, {5} };
> 
> The compiler might warn about the incomplete initializer, but C
> defines the effect: The extras are initialized to zero-value.  You
> might be able to suppress the warning with a C99-style initializer:
> 
>     struct foo foos[5 + NUM_EXTRA_FOOS] =
>     { {1}, {2}, {3}, {4}, {5}, [5+NUM_EXTRA_FOOS-1] = {0} );
> 
> ... or even
> 
>     struct foo foos[] =
>     { {1}, {2}, {3}, {4}, {5}, [5+NUM_EXTRA_FOOS-1] = {0} );
> 

There I go over-thinking again.  Thanks!

-- 
========================================================================
Ian Pilcher                                         arequipeno@gmail.com
"If you're going to shift my paradigm ... at least buy me dinner first."
========================================================================

[toc] | [prev] | [next] | [standalone]


#24189

FromPhilip Lantz <prl@canterey.us>
Date2012-08-03 16:46 -1000
Message-ID<MPG.2a8610986dd3e9ea98968e@news.eternal-september.org>
In reply to#24186
Ian Pilcher wrote:
> I need to create a static array of structures with the following
> characteristics:
> 
> * The first few members of the array are pre-initialized
> * The remaining members of the array are initialized to "zero"
> * The number of additional members is determined by a #defined constant,
>   independently of the number of pre-initialized members
> 
> Here's what I've come up with:
> 
> 
> #define NUM_EXTRA_FOOS     5
> 
> struct foo {
>     int data;
> };
> 
> static struct {
>     struct foo builtin[5];
>     struct foo extra[NUM_EXTRA_FOOS];
> } all_foos = {
>     { { 1 }, { 2 }, { 3 }, { 4 }, { 5 } },
>     { { 0 } }
> };
> 
> #define foos  all_foos.builtin
> 
> I believe that I can effectively use foos[] as an array with 10 (5 +
> NUM_EXTRA_FOOS) elements.
> 
> * Is my belief correct?

It's undefined behavior, but it will work with most, if not all, 
compilers.

> * Is there any danger of the compiler inserting unwanted padding between
>   the builtin and extra members of the anonymous struct?

A compiler is allowed to add padding between any two structure members, 
but I doubt that any would add padding here.

> * Is there a better way to do this?

Yes, this is much better:

#define NUM_EXTRA_FOOS     5

struct foo {
    int data;
};

static struct foo foos[5+NUM_EXTRA_FOOS] = {
    { 1 }, { 2 }, { 3 }, { 4 }, { 5 },
};

All members beyond those for which there are explicit initializers are 
guaranteed to be initialized to 0.

When I was first reading the question, I guessed that you would want the 
compiler to count the number of initializers and then add NUM_EXTRA_FOOS 
to that, but your example didn't show it, so I didn't try to answer that 
question. (I'm not sure whether there's an answer; I think there might 
be, but I suspect it would be ugly.)

[toc] | [prev] | [next] | [standalone]


#24204

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-08-04 16:19 +0200
Message-ID<501D2F88.5070300@loria.fr>
In reply to#24186
Am 04.08.2012 04:05, schrieb Ian Pilcher:
> I need to create a static array of structures with the following
> characteristics:
> 
> * The first few members of the array are pre-initialized
> * The remaining members of the array are initialized to "zero"
> * The number of additional members is determined by a #defined constant,
>   independently of the number of pre-initialized members
> #define NUM_EXTRA_FOOS     5


Yes this can be done even without much preprocessor magic.

Defining your initializers in a macro

#define FIRST_ELEMS { 1 }, { 2 }, { 3 }, { 4 }, { 5 }

and then replace your struct definition by just an array where the size
expression is constructed from the sizeof of a compount literal.

struct foo all_foos[NUM_EXTRA_FOOS + sizeof((struct foo[]){
FIRST_ELEMS})/sizeof(struct foo)] = {
       FIRST_ELEMS,
       };

Preprocessor magic can also be used to generated some fixed length list
of initializers, if you prefer that, but this is a bit more involved.

Jens

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web