0

please could anyone help me why such a definition of symbolic constants yields error definition of following static variables within functions: error: storage size of ‘variable’ isn’t constant

        #define SAMPLE_RATE 200 /* Sample rate in Hz. */
        #define MS_PER_SAMPLE   ( (double) 1000/ (double) SAMPLE_RATE)
        #define MS10    ((int) (10/ MS_PER_SAMPLE + 0.5))
        #define MS25    ((int) (25/MS_PER_SAMPLE + 0.5))
        #define MS30    ((int) (30/MS_PER_SAMPLE + 0.5))
        #define MS80    ((int) (80/MS_PER_SAMPLE + 0.5))
        #define MS95    ((int) (95/MS_PER_SAMPLE + 0.5))
        #define MS100   ((int) (100/MS_PER_SAMPLE + 0.5))
        #define MS125   ((int) (125/MS_PER_SAMPLE + 0.5))
        #define MS150   ((int) (150/MS_PER_SAMPLE + 0.5))
        #define MS160   ((int) (160/MS_PER_SAMPLE + 0.5))
        #define MS175   ((int) (175/MS_PER_SAMPLE + 0.5))
        #define MS195   ((int) (195/MS_PER_SAMPLE + 0.5))
        #define MS200   ((int) (200/MS_PER_SAMPLE + 0.5))
        #define MS220   ((int) (220/MS_PER_SAMPLE + 0.5))
        #define MS250   ((int) (250/MS_PER_SAMPLE + 0.5))
        #define MS300   ((int) (300/MS_PER_SAMPLE + 0.5))
        #define MS360   ((int) (360/MS_PER_SAMPLE + 0.5))
        #define MS450   ((int) (450/MS_PER_SAMPLE + 0.5))
        #define MS1000  SAMPLE_RATE
        #define MS1500  ((int) (1500/MS_PER_SAMPLE))
        #define DERIV_LENGTH    MS10
        #define LPBUFFER_LGTH ((int) (2*MS25))
        #define HPBUFFER_LGTH MS125#define WINDOW_WIDTH MS80            // Moving window integration width.
    #define FILTER_DELAY (int) (((double) DERIV_LENGTH/2) + ((double) LPBUFFER_LGTH/2 - 1) + (((double) HPBUFFER_LGTH-1)/2) + PRE_BLANK)  // filter delays plus 200 ms blanking delay
    #define DER_DELAY   WINDOW_WIDTH + FILTER_DELAY + MS100



    int lpfilt( int datum ,int init)
        {
        static long y1 = 0, y2 = 0 ;
        static int data[MS_PER_SAMPLE], ptr = 0 ;
        .....

int lpfilt( int datum ,int init)
    {
    static int data[MS_PER_SAMPLE], ptr = 0 ;
....
int hpfilt( int datum, int init )
    {
    static int data[HPBUFFER_LGTH], ptr = 0 ;
...


int deriv1(int x, int init)
    {
    static int derBuff[DERIV_LENGTH], derI = 0 ;
...

int deriv2(int x, int init)
    {
    static int derBuff[DERIV_LENGTH], derI = 0 ;
...
int mvwint(int datum, int init)
    {
    static int data[WINDOW_WIDTH], ptr = 0 ;
...

I haven't a clue what the problem might be, no matter if I retype the result of calculation with (int) it still yields an error. Is retyping not allowed in symbolic constant definition?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Ivo Hora
  • 49
  • 4
  • You may not use a double values as the size of an array. – Vlad from Moscow Feb 14 '21 at 20:18
  • 2
    Please edit your code into a proper [mre]. One *complete* function (closing brace and no "...") and one or two macros should be enough to reproduce the error (which you should copy verbatim). Dumping poorly formatted, redacted and grossly ill-formed code on us to sift through isn't helping us to help you. – StoryTeller - Unslander Monica Feb 14 '21 at 20:22
  • To compile it your compiler has to have this as an extension, clang compilers it without any problems, gcc fails (is more conforming) https://godbolt.org/z/8nezP6 – 0___________ Feb 15 '21 at 21:15

3 Answers3

0

The expression used in this manifest constant

#define MS_PER_SAMPLE   ( (double) 1000/ (double) SAMPLE_RATE)

has the type double.

It is not an integer constant expression.

So you may not use this manifest constant as a size of an array as for example in this declaration.

static int data[MS_PER_SAMPLE], ptr = 0 ;

You could define the constant as for example

#define MS_PER_SAMPLE   ( ( int ) ( 1000.0 / SAMPLE_RATE ) )

Or keeping the manifest constant declaration as is you could write

static int data[( int )MS_PER_SAMPLE], ptr = 0 ;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you, I tried this: #define MS_PER_SAMPLE ( ( int ) ( 1000.0 / SAMPLE_RATE ) ) and the error for first variable is gone, but appears for this: qrsfilt.c:125:13: error: storage size of ‘data’ isn’t constant static int data[HPBUFFER_LGTH], ptr = 0 ; – Ivo Hora Feb 15 '21 at 19:16
  • @IvoHora Without seeing the result code I can say nothing. Relative to the error message the reason is the same or the value of the array size if equal to 0. Close the question and ask a new providing a corresponding code. – Vlad from Moscow Feb 15 '21 at 19:27
  • Thank you, I put it to the answer, hope it is also fine – Ivo Hora Feb 15 '21 at 20:29
0

Why static definition of variable in C fails while compiling?

You cannot use + 0.5 in your constants. Research how to round an integer using only integers.

The array size has to be a constant expression. From cppreference constant expression:

An integer constant expression is an expression that consists only of

  • [... other points ....]
  • floating constants, but only if they are immediately used as operands of casts to integer type

The double value 0.5 is not "immediately casts" (like (int)0.5), but is used with operator + to add an int with it. Thus the error.

Looking at your code, the proof of concept could look like this:

// the simplest based on https://stackoverflow.com/questions/2422712/rounding-integer-division-instead-of-truncating
// but see also https://elixir.bootlin.com/linux/v4.17/source/include/linux/kernel.h#L132
#define DIV_ROUND(x, d)  ((x + (d / 2)) / d)

#define SAMPLE_RATE 200 /* Sample rate in Hz. */
#define MS_PER_SAMPLE   (1000 / SAMPLE_RATE)
#define MS125   DIV_ROUND(125, MS_PER_SAMPLE)
#define HPBUFFER_LGTH MS125
static int data[HPBUFFER_LGTH];

Because I see (int) spawned everywhere in your code, it would be a great time to read about types of integer constants, about conversions. Because you work with macros, be sure to understand macro pitfalls.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
0

KamilCuk was right, constant 0.5 is not valid in my symbolic constant. Changing 0.5 to 1/2 and also removing all casting to (double) solved the issue. Thank you very much.

Ivo Hora
  • 49
  • 4