Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I do something like #define ARRAY(size) char[##size##] in C?

Tags:

c

gcc

avr

avr-gcc

I'm trying to define a macro to generate a structure on my global scope like the code above:

#define BUFFER(size) \
struct { \
    unsigned short size = ##size; \
    unsigned short readIndex = 0; \
    unsigned short writeIndex = 0; \
    unsigned char dataPtr[##size##]; \
}

BUFFER(10) buffer10bytes;
BUFFER(50) buffer50bytes;

The problem is that apparently gcc is not evaluating this macro. Is it possible to archive? How?

Here is my compiler error:

In file included from ../usart.c:12:0:
../usart.c:14:8: error: expected identifier or '(' before numeric constant
 BUFFER(10) buffer10bytes;
        ^
../buff.h:24:17: note: in definition of macro 'BUFFER'
  unsigned short size = ##size; \
                 ^
../buff.h:24:22: error: pasting "=" and "10" does not give a valid preprocessing token
  unsigned short size = ##size; \
                      ^
../usart.c:14:1: note: in expansion of macro 'BUFFER'
 BUFFER(10) buffer10bytes;
 ^
../buff.h:25:27: error: expected ':', ',', ';', '}' or '__attribute__' before '=' token
  unsigned short readIndex = 0; \
                           ^
../usart.c:14:1: note: in expansion of macro 'BUFFER'
 BUFFER(10) buffer10bytes;
 ^
../buff.h:27:23: error: pasting "[" and "10" does not give a valid preprocessing token
  unsigned char dataPtr[##size##]; \
                       ^
../usart.c:14:1: note: in expansion of macro 'BUFFER'
 BUFFER(10) buffer10bytes;
 ^
../usart.c:14:8: error: pasting "10" and "]" does not give a valid preprocessing token
 BUFFER(10) buffer10bytes;
        ^
../buff.h:27:26: note: in definition of macro 'BUFFER'
  unsigned char dataPtr[##size##]; \
                          ^
../usart.c:15:8: error: expected identifier or '(' before numeric constant
 BUFFER(50) buffer50bytes;
        ^
../buff.h:24:17: note: in definition of macro 'BUFFER'
  unsigned short size = ##size; \
                 ^
../buff.h:24:22: error: pasting "=" and "50" does not give a valid preprocessing token
  unsigned short size = ##size; \
                      ^
../usart.c:15:1: note: in expansion of macro 'BUFFER'
 BUFFER(50) buffer50bytes;
 ^
../buff.h:25:27: error: expected ':', ',', ';', '}' or '__attribute__' before '=' token
  unsigned short readIndex = 0; \
                           ^
../usart.c:15:1: note: in expansion of macro 'BUFFER'
 BUFFER(50) buffer50bytes;
 ^
../buff.h:27:23: error: pasting "[" and "50" does not give a valid preprocessing token
  unsigned char dataPtr[##size##]; \
                       ^
../usart.c:15:1: note: in expansion of macro 'BUFFER'
 BUFFER(50) buffer50bytes;
 ^
../usart.c:15:8: error: pasting "50" and "]" does not give a valid preprocessing token
 BUFFER(50) buffer50bytes;
        ^
../buff.h:27:26: note: in definition of macro 'BUFFER'
  unsigned char dataPtr[##size##]; \
                          ^
make: ** [usart.o] Erro 1
like image 858
ylima Avatar asked Feb 10 '23 11:02

ylima


1 Answers

Take out the ##. That is for creating a new token from two tokens; but you are not doing that here, you do actually just want two tokens.

Also you cannot use the same name for a variable as you do for the macro parameter.

Another issue is that you can't put initializers inside the struct definition. So you'll have to modify the form of your macro, e.g.:

#define DECLARE_BUFFER(size_, name) \
struct { \
    unsigned short readIndex;
    unsigned short writeIndex;
    unsigned char dataPtr[size_]; \
} name = { 0 }

BUFFER(10, buffer10bytes);
BUFFER(50, buffer50bytes);

I have removed size as it seemed redundant: you can always go sizeof X.dataPtr to get that value. (note: Ptr is a poor name for an array). But you could include size if needed (as suggested by Remy in comments) if it's meant to change to represent the contents of the buffer or something:

#define DECLARE_BUFFER(size_, name) \
struct { \
    unsigned short size;
    unsigned short readIndex;
    unsigned short writeIndex;
    unsigned char dataPtr[size_]; \
} name = { size_, 0 }
like image 152
M.M Avatar answered Feb 13 '23 02:02

M.M