tables with 0 elements

Posted on 2001-09-17
Last Modified: 2010-04-15
Below is a snippet of code.  It compiles with gcc, but
not cc.  My question is, why doesn't cc like it, and how
do I modify the declaration of the table to get the
outcome I want (which is to have 'x = 0').

(If you're curious - the idea is to have a table such that an action is performed for each entry in the table.  If there are zero entries, then zero actions are performed.  This is intended to be a default case - other people or perhaps even a script might add elements to the table later depending on a particular need.)

Any help would be appreciated.

#include <stdio.h>
#include <stdlib.h>

typedef struct
   int a;
   int b;

MYSTRUCT mytable[] =

#define num_elements(a)   (sizeof(a)/sizeof(a[0]))

void main(void)
   int x = num_elements(mytable);

   printf("number of elements: %d\n", x);
Question by:red5
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Expert Comment

ID: 6487921
- sizeof(a) mytable is implementation defined (i.e. not guaranteed to be 0, or 1, or whatever), if there are no entries.
- compiler may legitimately emit at least a warning about the index of a[0] being out of range. I have no Standard here, but If my mind serves me right, out-of-bound access (even when detectable at compile time) "undefined behaviour". Which means, the program could wipe your entire hard disk and youcan't even blame the compiler writers.

What does mean "cc doesn't like it". I expect it outputs something else than "mytable.c: don't like this file".

(i.e. compiler error message, runtime output...)

 a) introduce a "table end" indicator, e.g. { 0, 0 }, that must be present. Iterate the table until you get there.
Advantage: your app could work with any MYSTRUCT * - even if it was allocated dynamically. Disadvantage: If someone deletes the end indicator, the program blows up.

b) sizeof(a)/sizeof(MYSTRUCT) is a bit safer - but you are still not guaranteed about the result of sizeof(a) - so this might work with cc, but break wih dd.

c) get over this (admittedly convenient) C style stuff, and pass a length somehow.

d) Do it as MFC/ATL does: use Open / Entry / Close" macros for the table.


Expert Comment

ID: 6487929
d) elaborated:

#define TABLE_BEGIN(name) MYSTRUCT name[] = {
#define TABLE_ENTRY(a,b)  { a, b },
#define TABLE_END         { 0, 0 } };
// <-- uses "end indicator" method

Author Comment

ID: 6487963
I have considered some of the alternatives you suggested.
However, there are some backward compatibility issues.  Changing how the table works causes the existing tables that have already been created for various uses to no longer work.  I am hoping to avoid that situation.

Also, I am just curious.  What does the ANSI standard say on this issue?  I haven't yet found the magic sentence in my Kernighan/Ritchie book.
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 6487974
also, here is the output from cc:

"sizeoftest.c", line 12: syntax error before or at: }
"sizeoftest.c", line 12: warning: syntax error:  empty declaration
"sizeoftest.c", line 18: warning: null dimension: sizeof()
cc: acomp failed for sizeoftest.c

Expert Comment

ID: 6488210
I only have the C++ standard draft '96, but I guess the same applies to C: dcl.init.agr
"An  empty  initializer list {} shall not be used as the initializer for an array of unknown bound."

Which is (if it aplpies to ASNI C, too) a perfectly valid reason for cc to moan.

As I don't have any other idea while retaining the syntax, and i don't know what you can change, you're out of luck.

Based on the info I have, probably forcing an "default do-nothing" argument proves best, unless of curse you have existing source with hundreds of such tables...


Accepted Solution

Triskelion earned 34 total points
ID: 6489147
Why don't you put a dummy record in it and make the logic say (perform on (number of elements minus one))?
LVL 31

Expert Comment

ID: 6490042
I agree with peterchen ... i.e. you can add a dummy-entry at the end of all such tables and
define the macro like this:
#define num_elements(a)   ((sizeof(a)/sizeof(a[0]))-1)

with this I think you won't have to modify any other code...

Assisted Solution

_serega earned 33 total points
ID: 6493940
ANSI C forbids empty initializer braces
try to use -Wall -ansi -pedantic
switches to gcc
LVL 11

Assisted Solution

alexo earned 33 total points
ID: 6614665
C89 (the 1989 ANSI C standard) does not allow empty initializer lists nor zero-sized arrays.  C99 has some extensions to that effect.
LVL 45

Expert Comment

ID: 9445365
No comment has been added lately and this question is therefore classified abandoned.

If asker wishes to close the question, then refer to

Otherwise, I will leave a recommendation in the Cleanup topic area that this question is:
PAQed with A grade to peterchen

Please leave any comments here within the next seven days. It is assumed that any participant not responding to this request is no longer interested in its final disposition.


EE Cleanup Volunteer

Author Comment

ID: 9451462
I don't really even remember what this was for anymore.  I must have found a solution, but don't remember what.  Since the num-1 solution seems plausible (even tho I don't remember if it was practical for for needs) I'll accept that as the answer.  Thanks

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question