Max
Max

Reputation: 2859

Floating point math in macro constants, while maintaining integer-ness

I have some macros like the following:

#define THING_LENGTH (512)
#define MAX_COUNT (4096*8)
#define MAX_LENGTH ((int32)((float)(MAX_COUNT*THING_LENGTH)*1.5))

Which are being substituted in this:

typedef struct Writes {
    char buf[MAX_LENGTH];
    char buf2[MAX_COUNT];
    ...
} Writes;

To give this preprocessed result:

typedef struct Writes {
    char buf[((int32)((float)((4096*8)*(512))*1.5))];
    char buf2[(4096*8)];
    ...
} Writes;

Which is giving me this warning/error:

variably modified ‘buf’ at file scope

What's the best way to maintain the MAX_COUNT*THING_LENGTH*1.5 logic in the macro, but have it work? And maintain all the constants as constant, and integer?

Upvotes: 0

Views: 2094

Answers (2)

chux
chux

Reputation: 154218

This question is duplicated many times.

The issue is that either:
1. floating point constants are not consider that constant for array size determination and/or
2. The array size is from a variable. (but not in this OP's case)

Note: remember that using (x*3)/2 idiom instead of (x*1.5) truncates toward 0, so if x was 7, (x*3)/2 would be 10 and not 11. Depending on what you want, you may want (x*3 + 1)/2 to insure ample MAX_LENGTH.

Upvotes: 2

acegs
acegs

Reputation: 2809

Just don't use any float in math operations of constants. Here:

//---mul by 3, then div by 2
#define MAX_LENGTH ((MAX_COUNT*THING_LENGTH * 3) / 2 )

//---more optimized version
#define MAX_LENGTH_PARTIAL (MAX_COUNT*THING_LENGTH)
#define MAX_LENGTH (((MAX_LENGTH_PARTIAL << 1 ) + MAX_LENGTH_PARTIAL) >> 1 )

Upvotes: 2

Related Questions