Federico
Federico

Reputation: 1090

Alternatives to global array or "array" of '#define's?

My current code uses some #defines to have all the constants in a single .h file.

A new modification to the program specification is coming this way and this will require some of the constants to be case-dependant, i.e. a variable will set the case (of 3 possible) and according to it the appropriate value must be used for some of these constants, e.g:

#define CONSTANT1 1.0F
#define CONSTANT2 2.0F

float foo(float var)
{
    return (CONSTANT1 + CONSTANT2*var);
}

I can currently think of approaching this problem in 2 ways:

Way1- have a #define for each of the possible values, implement a switch-case with 3 copies of the code and in each use the corresponding constant

#define CONSTANT1_a 1.0F
#define CONSTANT2_a 2.0F

#define CONSTANT1_b 2.0F
#define CONSTANT2_b 3.0F

#define CONSTANT1_c 3.0F
#define CONSTANT2_c 4.0F

switch(var_case)
{
case 0:
     float foo(float var)
     {
         return (CONSTANT1_a + CONSTANT2_a*var);
     }
case 1:
     float foo(float var)
     {
         return (CONSTANT1_b + CONSTANT2_b*var);
     }
case 2:
     float foo(float var)
     {
         return (CONSTANT1_c + CONSTANT2_c*var);
     }
}

Way2- have the constants no more as #defines, but as global arrays defined at the top of the corresponding file and have a single implementation of the code with the "case" that selects the position in the array

float CONSTANT1 [] = {1.0F,2.0F,3.0F};
float CONSTANT2 [] = {2.0F,3.0F,4.0F};

float foo(float var)
{
    return (CONSTANT1[var_case] + CONSTANT2[var_case]*var);
}

I tend towards the second solution, as it seems more maintanable and clean, but the use of global arrays does not sound great. Is there an alternative? Is there a way to have a #define containing an array? (or something equivalent)

EDIT: my apologies for not mentioning before. The code must be C89 (ANSI C).

Upvotes: 0

Views: 199

Answers (2)

user694733
user694733

Reputation: 16043

Using global arrays for constants is fine. Your preprocessor constants were already global in the first place. Just add const and you are done.

constants.c

const float CONSTANT1 [] = {1.0F,2.0F,3.0F};
const float CONSTANT2 [] = {2.0F,3.0F,4.0F};

constants.h

extern const float CONSTANT1 [];
extern const float CONSTANT2 [];

Or, if you want to make arrays private to your current compilation unit, add static.

static const float CONSTANT1 [] = {1.0F,2.0F,3.0F};

Upvotes: 5

Vincent
Vincent

Reputation: 329

I can't verify this right now, but this might work: A #define Macro can be an array, or pretty much anything. Do it like this:

#define CONSTANTS int temp[]={1,2,3,4};
//.. Later..
int x = (CONSTANTS)[2];

All a #define does is say to the compiler: before you compile this, replace every instance in the code of the defined constant ( in this case CONSTANTS) with whatever comes after (in this case "temp[]={1,2,3,4}"). So the above code would be compiled as

int x = (temp[]={1,2,3,4})[2];

This becomes unreliable though, because temp would have to be a reserved variable name within that scope. I recommend using the switch or a standin variable plus a couple of ternary conditionals for a one-liner.

Upvotes: -3

Related Questions