1

我知道以下是有效代码:

#define SOMEMACRO 10
int arr[SOMEMACRO];

这将导致int arr[10].

如果我想制作一个 2 倍大小的数组(并且仍然需要其他地方的原始宏),这是有效的代码吗?

#define SOMEMACRO 10
int arr[2 * SOMEMACRO];

这将是int arr[2 * 10]在预编译之后。这仍然被编译器视为常量表达式吗?

快速浏览后它似乎有效,但这是定义的行为吗?

4

4 回答 4

2

是的,它会起作用。MACRO 将在编译时放置,因此a[2*SOMEMACRO]将成为a[2*10]完全有效的。

要检查预处理的内容,您可以使用cc -E foo.c选项

于 2013-07-30T10:31:20.490 回答
1

是的,您可以使用此表达式。它不会导致UB。
请注意,数组下标可能是整数表达式

#define i  5 
#define j  4
int a[i+j*10] = 0;

下标的值i+j*10将在编译期间计算。

于 2013-07-30T10:30:08.707 回答
1

这仍然被编译器视为常量表达式吗?

是的。这就是常量表达式和文字之间的区别:常量表达式不必是单个文字,它可以是可以在编译时计算其值的任何表达式(即文字或其他常量表达式的组合)。

(只是为了清楚起见:当然文字仍然被认为是常量表达式。)

但是,在 C 中,数组的大小不必是编译时常量。C99 和 C11 支持可变长度数组 (VLA),因此

size_t sz = // some size calculated at runtime;
int arr[sz];

也是有效的 C。

于 2013-07-30T10:34:43.387 回答
0

是的,只要它是一个有效数字,它就是一个常量表达式。如果您说它有效,那么您就知道编译器可以正常工作。

如你所知,我们做不到

int x;
scanf("%d", &x);
int arr[2 * x];

因为那不是一个常数。但是你写的是一个常数,所以你很高兴

于 2013-07-30T10:28:56.530 回答