我可以在 C 中执行类似 #define ARRAY(size) char[##size##] 的操作吗?

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

我正在尝试定义一个宏来在我的全局范围内生成一个结构,如上面的代码:

#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;

问题是 gcc 显然没有计算这个宏。 可以存档吗?怎么样?

这是我的编译器错误:

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

取出##。那是为了从两个令牌创建一个新令牌;但你在这里没有这样做,你实际上只想要两个令牌。

此外,您不能对变量使用与宏参数相同的名称。

另一个问题是您不能将初始值设定项放在结构定义中。所以你必须修改宏的形式,例如:

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

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

我删除了 size,因为它看起来多余:您可以随时转到 sizeof X.dataPtr 来获取该值。 (注意:Ptr 是一个糟糕的数组名称)。但是,如果需要 size (如 Remy 在评论中所建议的那样),如果它意味着更改以表示缓冲区的内容或其他内容,则可以包括 size

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