First, #define
defines a preprocessor macro. As others have mentioned, most style guides recommend the use of ALL_CAPS
for constants. The contents of the macro are replaced directly, so this:
#define SIZE 10
void test(void)
{
int ar[SIZE];
}
will become this, which defines a normal fixed-size array:
void test(void)
{
int ar[10];
}
This is a C99 variable-length array (VLA):
void test(void)
{
int size = 10;
int ar[size];
}
On a modern compiler with optimizations enabled, there is probably no difference. The compiler will see that size
never changes, and will probably generate the same code.
There might be subtle differences with regard to static analysis, but for the most part, their behavior is identical.
However, VLAs are more powerful than that. See this example:
void test(int size)
{
int ar[size];
}
Now the size of ar
will change each time test()
is called, according to the size
parameter. That means the stack layout and consumption will vary at runtime. This is similar to this pre-C99 code using alloca
:
void test(int size)
{
int * const ar = alloca(size * sizeof(int));
}
A key difference is that using sizeof()
on a VLA will return its runtime size, whereas sizeof(ar)
in that example would return the size of the pointer.
So if you were do do this:
int size = 10;
void test(void)
{
int ar[size];
}
Then the compiler would be forced to generate code which reads the global size
variable, and dynamically allocate the array on the stack.