26

Probably a naïve question - I used to program 20 years ago and haven't coded much since. My memory of how the C preprocessor works has atrophied significantly since then...

I am writing a very simple C program and I am trying to declare a few static global arrays, but the size of the arrays would be dependent (on a non-trivial way) on a MODE variable. Something like the simplified example below.

Two quick points: I know I could just size the arrays according to the largest size needed by any MODE, but I don't want to that because (unlike in the simplified example below) sometimes a handful of these dimensions are going to be extremely large while others are tiny.

Also, I want to use statically defined global arrays - rather than dynamically allocate them at runtime. I want the compiler to have the sizes at compile time.

//** Simplified example of what I'd like to do **//    
#define SIZE_LIST_1[5] = {2, 7, 23, 33, 12, 76}  // I don't think this is valid syntax 
#define SIZE_LIST_2[5] = {11, 65, 222, 112, 444}

#define MODE 4
#define S1 SIZE_LIST_1[MODE]
#define S2 SIZE_LIST_2[MODE] 

int a[S1], b[S2];
3
  • int SIZE_LIST_1[5] = {2,7...76}; Commented Oct 10, 2012 at 17:07
  • I don't see what you mean by a[S1]. what are you trying to do there? Commented Oct 10, 2012 at 17:10
  • 2
    By a[S1], I am trying to declare a global array 'a' with S1 elements, where S1 was defined based on the value of mode. Commented Oct 10, 2012 at 17:15

4 Answers 4

18

You need to define a bunch of helper macros first before you can do this in a simple way:

#define CONCAT(A,B)         A ## B
#define EXPAND_CONCAT(A,B)  CONCAT(A, B)

#define ARGN(N, LIST)       EXPAND_CONCAT(ARG_, N) LIST
#define ARG_0(A0, ...)      A0
#define ARG_1(A0, A1, ...)  A1
#define ARG_2(A0, A1, A2, ...)      A2
#define ARG_3(A0, A1, A2, A3, ...)  A3
#define ARG_4(A0, A1, A2, A3, A4, ...)      A4
#define ARG_5(A0, A1, A2, A3, A4, A5, ...)  A5
#define ARG_6(A0, A1, A2, A3, A4, A5, A6, ...)      A6
#define ARG_7(A0, A1, A2, A3, A4, A5, A6, A7, ...)  A7
#define ARG_8(A0, A1, A2, A3, A4, A5, A6, A7, A8, ...)      A8
#define ARG_9(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, ...)  A9
#define ARG_10(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...)    A10

/* above should be in a pp_helper.h header file or some such */

#define SIZE_LIST_1 ( 2,  7,  23,  33,  12,   76)
#define SIZE_LIST_2 (11, 65, 222, 112, 444, 1000)

#define S1 ARGN(MODE, SIZE_LIST_1)
#define S2 ARGN(MODE, SIZE_LIST_2)

#define MODE 4

int a[S1], b[S2];

There are a bunch of preprocessor 'libraries' you can get with the boilerplate code (boost PP, P99), or you can just roll your own. The main problem being that you need to define ARG macros based on the largest number of arguments you'll ever want to handle.

Sign up to request clarification or add additional context in comments.

Comments

17

I know I'm a little too late but you can also do this, which is way more simple, I don't think it's very fast but for small programs it'll do the trick

#include <stdio.h>
#define SIZE_LIST (int[]){2, 7, 23, 33, 12, 76}

int main(void)
{
    for (int i = 0; i < 6; i++)
        printf("%d\n", SIZE_LIST[i]);
    return (0);
}

Comments

12

Probably the best you can do is something like this:

#define SIZE_LIST_1_0 2
#define SIZE_LIST_1_1 7
#define SIZE_LIST_1_2 23
#define SIZE_LIST_1_3 33
#define SIZE_LIST_1_4 12

#define SIZE_LIST_2_0 11
#define SIZE_LIST_2_1 65
#define SIZE_LIST_2_2 222
#define SIZE_LIST_2_3 112
#define SIZE_LIST_2_4 444

#define MODE 4

#define S1 SIZE_LIST_1_##MODE
#define S2 SIZE_LIST_2_##MODE

int a[S1], b[S2];

3 Comments

Thank you Paul - that is a bit messy, but could solve the problem. I hadn't known you could do that. I take it there are no 'more elegant' ways of doing it?
No - the preprocessor is really very limited and was not designed for this kind of abuse. I'm not sure why this answer got an anonymous down-vote though - it's not very elegant but it solves the problem. Oh well...
I also see no reason why it should be down voted. Thank you again for the idea.
5

I'm afraid there is no such possibility.

I suggest the following approach instead:

#define MODE 0

#define DECLARE_ARRAYS_WITH_SIZES(S1, S2, S3) \
    int arr1[S1]; \
    int arr2[S2]; \
    int arr3[S3];

#if MODE == 0
DECLARE_ARRAYS_WITH_SIZES(3, 6, 7)
#elif MODE == 1
DECLARE_ARRAYS_WITH_SIZES(8, 2, 1)
#endif

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.