Reputation: 21
So I'm doing a course on C. One of the assignments is to look at and understand the code for sorting 5 grades(numbers). I copied the professor's code to MVS but it came up with errors. One of the issues I solved, as you can see by the comments in the code. But I don't understand how the professor managed to compile.
So my question is: how can the second error be solved?
int w[how_many];//error: expression must have a constant value
.
Anyone care to help?
I'm using Visual studio. Tried "disable language ext.", rename source file from .cpp to .c and changed to "compile as C code (/TC)"
#include <stdio.h>
#define SIZE 5
void print_array(int how_many, int data[], const char* str)
{
int i;
printf("%s", str);
for (i = 0; i < how_many; i++)
printf("%d\t", data[i]);
}
void merge(int a[], int b[], int c[], int how_many)
{
int i = 0, j = 0, k = 0;
while (i < how_many && j < how_many)
if (a[i] < b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
while (i < how_many)
c[k++] = a[i++];
while (j < how_many)
c[k++] = b[j++];
}
void mergesort(int key[], int how_many)
{
int j, k;
int w[how_many];//error: expression must have a constant value
for (k = 1; k < how_many; k *= 2)
{
for (j = 0; j < how_many - k; j += 2 * k)
merge(key + j, key + j + k, w + j, k);
for (j = 0; j < how_many; j++)
key[j] = w[j];
}
}
int main(void)
{
//const int SIZE = 5; // removed because of error and added #define SIZE 5
int a[SIZE] = { 67, 82, 83, 88, 99 };// error: needs constant value, solved by adding #define SIZE 5
print_array(SIZE, a, "My grades\n");
printf("\n\n");
mergesort(a, SIZE);
print_array(SIZE, a, "Sorted grades\n");
printf("\n\n");
return 0;
}
Upvotes: 2
Views: 168
Reputation: 23226
The solution is further down, but first, the failure here:
int w[how_many];//error: expression must have a constant value
is because the MSVC compiler does not support Variable-length Arrays (VLA).
C99
and newer family of ANSI C compilers support VLA.
So, the solution here is to get a different compiler.
Note:
VS 2019 (16.8) will include
/std:c11
and/std:c17
standards switches. See this blog post. Because the MSVC compiler does not support Variable-length Arrays (VLA) it does not claim C99 conformance. Note that these switches enable the new C99 preprocessor covered in this blog post
(From here: Is there any option to switch between C99 and C11 C standards in Visual Studio?)
So my question is: how can the second error be solved?
Before C99
, C programmers that did not know the length of an array until run-time used dynamic memory allocation. In your example, this:
int w[how_many];
could be implemented as:
int *w = calloc(how_many * sizeof(*w));
if(w)
{
memset(w, 0, how_many);//zero the new memory space. (VLA needs this too)
//use variable in code
...
free(w); //always free when done, (VLA does not require)
}
Edit to address OP later content added to post,
const int SIZE = 5;
int a[SIZE] = { 67, 82, 83, 88, 99 };
This is not a valid C
VLA as it is not (and never has been ) legal to initialize a VLA in C
. (It is however legal in C++
)
This however is legal: (as 5 is a constant value.)
#define SIZE 5
int a[SIZE] = { 67, 82, 83, 88, 99 };
Upvotes: 2
Reputation: 133988
That code is not proper standard C.
int main(void) {
const int SIZE = 5;
int a[SIZE] = { 67, 82, 83, 88, 99 };
}
is not valid C89, because it has a variable-length array. It is not valid C99, C11, or C18, because a variable-length array cannot be initialized.
It is valid C++ though, because an array whose dimensions are specified with a const int
is of static type.
Additionally Clang C compiler compiles it, but Gnu C Compiler rightfully refuses to compile:
% gcc vla.c
vla.c: In function ‘main’:
vla.c:49:5: error: variable-sized object may not be initialized
49 | int a[SIZE] = { 67, 82, 83, 88, 99 };
| ^~~
vla.c:49:21: warning: excess elements in array initializer
49 | int a[SIZE] = { 67, 82, 83, 88, 99 };
| ^~
vla.c:49:21: note: (near initialization for ‘a’)
vla.c:49:25: warning: excess elements in array initializer
49 | int a[SIZE] = { 67, 82, 83, 88, 99 };
| ^~
vla.c:49:25: note: (near initialization for ‘a’)
vla.c:49:29: warning: excess elements in array initializer
49 | int a[SIZE] = { 67, 82, 83, 88, 99 };
| ^~
vla.c:49:29: note: (near initialization for ‘a’)
vla.c:49:33: warning: excess elements in array initializer
49 | int a[SIZE] = { 67, 82, 83, 88, 99 };
| ^~
vla.c:49:33: note: (near initialization for ‘a’)
vla.c:49:37: warning: excess elements in array initializer
49 | int a[SIZE] = { 67, 82, 83, 88, 99 };
| ^~
vla.c:49:37: note: (near initialization for ‘a’)
% clang vla.c
% clang vla.c -pedantic
vla.c:49:11: warning: variable length array folded to constant array as an extension [-Wgnu-folding-constant]
int a[SIZE] = { 67, 82, 83, 88, 99 };
^~~~
1 warning generated.
Suggested solution: get yourself a new professor.
Upvotes: 1
Reputation: 11311
Re:
So my question is: how can the second error be solved?
int w[how_many];//error: expression must have a constant value.
You can allocate memory for that array w
like that:
int* w = malloc(how_many * sizeof(int));
Upvotes: 1