0

I have some macros defined such as

#define NUM_A 3
#define A1 10
#define A2 100
#define A3 8

The total count and the values are specific to the device. Now I need an array looks like

int Array[NUM_A]={A1, A2, A3};

Now, if the total number, NUM_A changes to 4, and I have defined the macro A4, but I forget to append A4 to the array. The actual Array would be {A1, A2, A3, 0}. There won't be error when compiling. The error is also hard to be found when running the program. It's more likely to be happen when I write the macros in the header file and declare the array in a source file. Can I write a looped macro to generate the array by the defined macros NUM_A, A1, A2 and A3? Or can I write an assert or something else to warn myself if the error occurs when compiling or running?

iuradz
  • 1,128
  • 1
  • 12
  • 25
  • Boost has tools to do this. I imagine they are C compatible... I mean, they must be, right? Anyway, the long and short is that you have to write horrid macro magic... but it _is_ possible. – Lightness Races in Orbit Oct 21 '14 at 13:27
  • Related: http://stackoverflow.com/q/19117228/535275 – Scott Hunter Oct 21 '14 at 13:28
  • 1
    @LightnessRacesinOrbit Boost is for C++, why "must" it be compatible with C? Any Boost code I've randomly looked at has always been heavily into templates. – unwind Oct 21 '14 at 13:29
  • What about simply omitting the number of elements in the declaration, as in http://stackoverflow.com/questions/9846920/define-array-in-c – Codor Oct 21 '14 at 13:29
  • @Codor that wouldn't help detect the case when the OP forgets to update the list of values to match the expected number of elements. – Graham Borland Oct 21 '14 at 13:30
  • @unwind: Because the Boost.Preprocessor library works solely with the C++ preprocessor, which is identical to the C preprocessor. Thus, the tools that Boost provides to achieve the OP's goals should be compatible with the language he's using. – Lightness Races in Orbit Oct 21 '14 at 15:41

3 Answers3

1

Just a question/suggestion.

Do you really need "NUM_A" ? Atleast from the code snippet point of view, it is not required. Not sure if you are using it elsewhere for some other purpose.

You can declare the array as:

int Array[] = {A1, A2, A3}; /* So this becomes the only place to be modified, just add A4 in the future. No confusion with array size */

NUM_A is equivalent to "sizeof Array / sizeof Array[0]".

Example:

  int arr[] = {A1, A2, A3};
  int i;

  for(i = 0; i < sizeof arr / sizeof arr[0]; i++)
  {
    printf("%d\n", arr[i]);
  }
Arjun Mathew Dan
  • 5,240
  • 1
  • 16
  • 27
0

You can assert that the array is of the expected size:

assert(sizeof(Array) == NUMA * sizeof(Array[0]));

That's a runtime check. There are various ways of doing it at compile-time depending on your compiler version; see Static assert in C

Community
  • 1
  • 1
Graham Borland
  • 60,055
  • 21
  • 138
  • 179
0

In addition to declaring your variable with open array operators as A.M.D. has shown:

  int arr[] = {A1, A2, A3};

You can also define a shorter representation of sizeof arr/sizeof arr[0], by defining a macro to replace that statement anywhere in your code where arr is defined like this:

#define ARR_SIZE sizeof arr/sizeof arr[0]  

The macro will evaluate to the number of array elements at run-time, And accommodates changes to number of elements in the array between run-times, with no need to edit the macro.

For arr[] = {1,2,5,8,9,3}; ARR_SIZE will evaluate to 6
For arr[] = {1,2,5,8,9,3,4,7,1,0,4}; ARR_SIZE will evaluate to 11

This is a useful code readability technique for things such as loops:

for(i=0;i< ARR_SIZE;i++); // is more readable

for(i=0;i< sizeof arr/sizeof arr[0];i++); // is less readable
ryyker
  • 22,849
  • 3
  • 43
  • 87