我知道以下是有效代码:
#define SOMEMACRO 10
int arr[SOMEMACRO];
这将导致int arr[10]
.
如果我想制作一个 2 倍大小的数组(并且仍然需要其他地方的原始宏),这是有效的代码吗?
#define SOMEMACRO 10
int arr[2 * SOMEMACRO];
这将是int arr[2 * 10]
在预编译之后。这仍然被编译器视为常量表达式吗?
快速浏览后它似乎有效,但这是定义的行为吗?
是的,它会起作用。MACRO 将在编译时放置,因此a[2*SOMEMACRO]
将成为a[2*10]
完全有效的。
要检查预处理的内容,您可以使用cc -E foo.c
选项
是的,您可以使用此表达式。它不会导致UB。
请注意,数组下标可能是整数表达式:
#define i 5
#define j 4
int a[i+j*10] = 0;
下标的值i+j*10
将在编译期间计算。
这仍然被编译器视为常量表达式吗?
是的。这就是常量表达式和文字之间的区别:常量表达式不必是单个文字,它可以是可以在编译时计算其值的任何表达式(即文字或其他常量表达式的组合)。
(只是为了清楚起见:当然文字仍然被认为是常量表达式。)
但是,在 C 中,数组的大小不必是编译时常量。C99 和 C11 支持可变长度数组 (VLA),因此
size_t sz = // some size calculated at runtime;
int arr[sz];
也是有效的 C。
是的,只要它是一个有效数字,它就是一个常量表达式。如果您说它有效,那么您就知道编译器可以正常工作。
如你所知,我们做不到
int x;
scanf("%d", &x);
int arr[2 * x];
因为那不是一个常数。但是你写的是一个常数,所以你很高兴