expression did not evaluate to a constant ERROR code - c

So I am trying to learn C and I am trying to make this code so it will sort of the array's elements from lowest to highest, it's obviously not complete but I just wanted to see the random numbers printed.
Anyway, I am getting an error E0028 & C2131 (Visual Studios) that says "expression must have a constant value" & "expression did not evaluate to a constant." The int goals[howMany];is where VS is telling me I have an error
int main()
{
int i, temp, swapped;
int howMany = 10;
int goals[howMany];
for (i = 0; i < howMany; i++) {
goals[i] = (rand() % 25) + 1;
}
printf("Original List\n");
for (i = 0; i < howMany; i++) {
printf("%d \n", goals[i]);
}
return 0;
}
This is exactly how the code is written out in the tutorial I am watching and they are using Code:Blocks. I know sometimes those two compilers can be different but I was hoping someone can let me know what's going on or how to fix this.

Visual studio doesn't support variable length arrays. C is a little tricky, and the compiler/flags you use matters. For example, if you were to compile with the gcc compiler, using the -std=c99 flag would allow you to run your code with no errors (since -std=c99 supports variable length arrays).
I'm not sure exactly how compilation in Visual Studio works, but that's your problem. I usually don't like C programming in VS for this reason. It's much easier for me to use something like Vim, and compile at the command like so that I can specify compiler settings.

In order to use rand(), you need to include the according lib and then "plant a rand seed" : take a look at C Rand Function

const howMany = 10;
This most likely is just the compiler you are using. I suppose it's a safe guard to prevent a segmentation fault. If howMany variable is changed after being used to initialize the array then a seg fault will will definitely result.A seg fault is when you access something out of bounds. If you try to change a const variable then the compiler will not let you.By making howMany const this will prevent any such errors.

Related

literal division at compile time

Assume the following code:
static int array[10];
int main ()
{
for (int i = 0; i < (sizeof(array) / sizeof(array[0])); i++)
{
// ...
}
}
The result of sizeof(array) / sizeof(array[0]) should in theory be known at compile time and set to some value depending on the size of the int. Even though, will the compiler do the manual division in run time each time the for loop iterates?
To avoid that, does the code need to be adjusted as:
static int array[10];
int main ()
{
static const int size = sizeof(array) / sizeof(array[0]);
for (int i = 0; i < size; i++)
{
// ...
}
}
You should write the code in whatever way is most readable and maintainable for you. (I'm not making any claims about which one that is: it's up to you.) The two versions of the code you wrote are so similar that a good optimizing compiler should probably produce equally good code for each version.
You can click on this link to see what assembly your two different proposed codes generate in various compilers:
https://godbolt.org/z/v914qYY8E
With GCC 11.2 (targetting x86_64) and with minimal optimizations turned on (-O1), both versions of your main function have the exact same assembly code. With optimizations turned off (-O0), the assembly is slightly different but the size calculation is still done at a compile time for both.
Even if you doubt what I am saying, it is still better to use the more readable version as a starting point. Only change it to the less readable version if you find an actual example of a programming environment where doing that would provide a meaningful speed increase for you application. Avoid wasting time with premature optimization.
Even though, will the compiler do the manual division in run time each time the for loop iterates?
No. It's an integer constant expression which will be calculated at compile-time. Which is why you can even do this:
int some_other_array [sizeof(array) / sizeof(array[0])];
To avoid that, does the code need to be adjusted as
No.
See for yourself: https://godbolt.org/z/rqv15vW6a. Both versions produced 100% identical machine code, each one containing a mov ebx, 10 instruction with the pre-calculated value.

C - Invalid syntax allowed by compiler?

When I learned C using Microsoft Visual Studio, it didn't allow me to create an array with a non-constant size. I had to either put a value like int arr[5]; or do #define size 5 and do int arr[size];. However today using Clion, I noticed it allows me to do the following:
#include <stdio.h>
int main()
{
printf("Enter a value: ");
int x;
scanf("%d", &x);
int arr2[x];
for (int i = 0; i < x; i++)
{
arr2[i] = i;
printf("Array at %d is %d.\n", i, arr2[i]);
}
return 0;
}
This C code compiles and runs without any problems -- no segment fault or anything. What's going on? Is this legal C code and I just learned in an IDE that didn't allow it, or is this invalid C code and I'm just using a bad compiler? On my other computer which is using Linux, I even installed GCC 7.2 and the same syntax is allowed. I don't understand. Is this a CLion issue, CMake issue, or a C lang issue?
My compiler and CMake are listed below. Thanks.
This is valid C. It is referred to as a variable length array (VLA). This feature was added to the language as part of the C99 standard.
MSVC is well known for not supporting many C99 and later features, including VLAs.

Matrix not zero-filled on declaration

I was trying to debug my code in another function when I stumbled upon this "weird" behaviour.
#include <stdio.h>
#define MAX 20
int main(void) {
int matrix[MAX][MAX] = {{0}};
return 0;
}
If I set a breakpoint on the return 0; line and I look at the local variables with Code::Blocks the matrix is not entirely filled with zeros.
The first row is, but the rest of the array contains just random junk.
I know I can do a double for loop to initialize manually everything to zero, but wasn't the C standard supposed to fill this matrix to zero with the {{0}} initializer?
Maybe because it's been a long day and I'm tired, but I could've sworn I knew this.
I've tried to compile with the different standards (with the Code::Blocks bundled gcc compiler): -std=c89, -std=c99, std=c11 but it's the same.
Any ideas of what's wrong? Could you explain it to me?
EDIT:
I'm specifically asking about the {{0}} initializer.
I've always thought it would fill all columns and all rows to zero.
EDIT 2:
I'm bothered specifically with Code::Blocks and its bundled GCC. Other comments say the code works on different platforms. But why wouldn't it work for me? :/
Thanks.
I've figured it out.
Even without any optimization flag on the compiler, the debugger information was just wrong..
So I printed out the values with two for loops and it was initialized correctly, even if the debugger said otherwise (weird).
Thanks however for the comments
Your code should initialize it to zero. In fact, you can just do int matrix[MAX][MAX] = {};, and it will be initialized to 0. However, int matrix[MAX][MAX] = {{1}}; will only set matrix[0][0] to 1, and everything else to 0.
I suspect what you are observing with Code::Blocks is that the debugger (gdb?) is not quite showing you exactly where it is breaking in the code - either that or some other side-effect from the optimizer. To test that theory, add the following loop immediately after the initialization:
``` int i,j;
for (i = 0; i < MAX; i++)
for (j = 0; j < MAX; j++)
printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j]);
```
and see if what it prints is consistent with the output of the debugger.
I am going to guess that what might be happening is that since you are not using matrix the optimizer might have decided to not initialize it. To verify, disassemble your main (disass main in gdb and see if the matrix is actually being initialized.

Code only works if all variables are set to 0 first. UB?

This code fails randomly by correctly identifying some numeric palindromes and failing on others.
#include <stdio.h>
int main(int argc, char *argv[])
{
int n, reverse = 0, temp;
printf("Enter a number to check if it is a palindrome or not\n");
scanf("%d",&n);
temp = n;
while( temp != 0 )
{
reverse = reverse * 10;
reverse = reverse + temp%10;
temp = temp/10;
}
if ( n == reverse )
printf("%d is a palindrome number.\n", n);
else
printf("%d is not a palindrome number.\n", n);
return 0;
}
For example, the above code incorrectly says "87678" isn't a numeric palindrome.
Checking the return of scanf() shows it's succeeding and printing the value of n is correct for input of 87678.
However the code correctly says "4554" is a palindrome.
However, by adding:
n = reverse = temp = 0;
before the first printf() the program appears to work correctly all the time. So what is happening in the first version? Is this some sort of undefined behavior when the variables aren't initialized before use?
EDIT: Will later provide the assembly of the compiled version that is failing to see what the compiler is doing.
Unless sizeof(int) is less than 4, you've either hit a compiler bug, your hardware is malfunctioning, or you have some form of data corruption going on in your system.
To answer the question: no, there's no undefined behavior anywhere in your program (assuming the scanf() really doesn't fail).
Try running memtest on your system to rule out RAM issues: http://www.memtest.org
It sounds very much like you have a compiler error since this works with later versions of gcc. I'd be very interested to see the output of gcc -S (pastebin please?) and also to know the compile command you are using. (optimization level especially).
Unlike Java, C does not have a default value for int. You can refer to this post as it discuss this similar problem.

why does adding a printf("A") make my code run, and removing it makes it crash

I have the following code in C:
while(tempNode!=NULL) {
int pos = pathNodesCount-1-i;
pathNodes[pos] = tempNode;
//printf("A");
euclidianLength += tempNode->g;
i = i+1;
tempNode = tempNode->parent;
}
if I leave the printf("A") statement commented out, and then compile and run my code, I will get an "application stopped running" Windows error. If I uncomment the printf("A") line, recompile and run, the application will run to its end (printing "A" to the console along the way). Why?
The environment is:
Windows 7 32bit
MinGW32 20120426 (and I've added MSys 1.0)
Eclipse Juno for C/CPP
== UPDATE
I've tracked my error. I won't post the exact code as it is too long, but it was a case of creating a char array, and then adding characters at wrong indexes. Something like this:
int otherCrap() {
char* c = malloc(10*sizeof(char));
int i = 0;
for(i = 0; i<13; i++) {
c[i]='a';
}
c[15] = '\0';
printf("A");
printf(c);
return 0;
}
Fixing the thing so that the chars were placed inside the array only at existing indexes, and also ading '\0' char as the last element in the array fixed the issue. However I'm still not clear as to why, when the code was bad, adding a printf('A') before printing the char array didn't result in a runtime error. From the answers received so far I am to understand that this falls under "undefined behavior".
Probably because some error in the code causes undefined behavior. Having the code then appear to "work" in the presence of a printf() is fine.
That indexing logic counting backwards looks scary; verify that it's correct. Print the index before using it, compare to the known size of the pathNodes array, if you have one. Beware of the index turning negative or overrunning the capacity of pathNodes.

Resources