Why is variable-length array working in this C code? - c

#include "stdio.h"
int main()
{
int n;
printf("Enter n:\n");
scanf("%d",&n);
int arr[n][n];
arr[3][3] = 4;
printf("%d",arr[3][3]);
getchar();
return 0;
}
Wasn't using int arr[n], where n is a variable, illegal in C? I am trying to understand what's happening here. Apparently the code works on my clang LLVM compiler and on IDEOne and on Codeblocks. I guess the compiler is just making things easy for me, by doing automatic memory allocation. But another astounding fact is that when I try to set n to 1, 2 or 3 it still works.

Variable length arrays are allowed by C standard since C99. Note that they are still not allowed by C++
standard.
Also important point to note is for versions before c99 and for most C++ compilers variable length arrays are supported by implementations in the form of extensions.

Related

Pointer to array of runtime-determined size pre-C99

Before C99, does the C standard allow defining or casting to pointers to arrays of length determined at runtime?
I understand that the standard doesn't allow variable length arrays before C99, but whether pointers to arrays of runtime-determined size are allowed is not obvious to me, since the compiler knows how much memory to allocate for a pointer at compile time, unlike the array.
gcc 10.1.0 allows it, even with -std=c90, but I am curious about whether the standard allows it rather than whether specific compilers do. This question is very similar, but the answer doesn't talk about the standard.
Here is a code example:
#include <stdio.h>
int f() {
int a;
scanf("%d", &a)
return a;
}
int main() {
int dim1 = f();
int dim2 = 2*dim1;
int (*p)[dim1][dim2]; // is this allowed pre-C99?
return 0;
}
This is a constraint violation. A conforming C89 compiler must issue a diagnostic for this program.
3.5.4.2 Array declarators
Constraints
The expression that specifies the size of an array shall be an integral constant expression that has a value greater than zero.
With gcc use -std=c90 -pedantic to get (mostly) conforming mode.

Array size should be known at compile time

I wrote a simple code where I am creating array without a fixed size. I tried compiling the code in gcc and it is working fine. Please explain why this is working array size should be supposed to be known at compile time.
Here's the code I have used.
void f(int k)
{
int a[k];
.....//some operation
}
int main()
{
int i = 10;
f(10);
return 0;
}
This feature is known as VLA or variable length array. This is not supported in all C standards. In recent C standards like C11 and C99, it is supported, but not in older C Standards as 'C89'.
If you're using gcc, please have a look at the compiler documentation regarding this.

How to create a pre defined variable array in C

I am trying to create an array according to the size that the user inputs but it does not seem to be working for c programming. The following are my codes:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int x, y;
scanf("%d", &x);
scanf("%d", &y);
double arr[x][y];
}
The compiler keeps returning an error of" Error: Expression must have a constant value. at the line double ... could anyone help point out the error?
You have two choices:
Either use a decent C compiler that supports C99 (or later) and variable-length arrays (I'd go with this approach, personally);
or if that is not possible, or the resulting array would be too large to fit in a block-scope variable (causing, for example, a stack overflow), you can use malloc(); however, you won't be able to create a true two-dimensional array using that approach, only a pointer-to-pointer, which may or may not be what you are looking for.
The code can work in C99 mode or when the compiler supports VLA(variable length arrays) as an extension (e.g, GCC supports VLA as GNU extesnion).
In C89, you have to use pointers with dynamic memory to simulate.
Older C standards don't provide support for arrays that do not have compile-time sizes:
int array[42];
char text[] = "Hello World";
int numbers = { 1, 2, 3, 4 };
(in the case of the latter two examples, the size is derived from the data)
You either need a newer compiler, to specify the -std=c99 if you are using GCC, or you need to allocate memory for the array yourself.
You're using a C89 (Visual Studio? Though that would give you an error on the declaration of arr next) or a C++ compiler. VLA's (Variable Length Arrays) are a C99 feature.
You need to allocate the memory in run-time . The compiler doesn't allow the declaration of arrays becuase it does not know the size of the array before hand . You need to use malloc() to allocate memory

for loop initial declaration error

In my code I can't initialize variables in for loop initialization part.
When I write this code:
long unsigned int arr[3][3];
char str[50];
for(;gets(str);)
{
int temp=0;
for(int i,j,k=0; str[k]!='\0'; k++){ if(str[k]!=' ')temp=temp*10+(str[k]-48);
the compiler shows
error: 'for' loop initial declarations are only allowed in c99 mode
I have no idea what that means,
but if I write my code like this:
long unsigned int arr[3][3];
char str[50];
for(;gets(str);)
{
int temp=0;
int i,j,k=0;
for(; str[k]!='\0'; k++){ if(str[k]!=' ')temp=temp*10+(str[k]-48);
it works fine.
Why is this happening?
Declaring variables in loops like
for (int i = 0; ...; ...)
was new in the C99 standard, and wasn't allowed in the earlier standards. What the error message tells you is that your compiler is set up to compile using an earlier standard, and so you can't use declarations inside for statements.
You either have to remove the declaration from inside the for statement, or tell the compiler to use a later standard when compiling. Telling the compiler to use a later version can be done by adding the flag -std=c99 if you have GCC or clang.
You are using a compiler that only supports C89, or the compiler is in the mode that supports C89 only. The declarations of variables must in the beginning of a block in C89. It's not a limit anymore in C99 or C++.
Change to C99 mode or put the declaration of i,j,k in the beginning of the block. The way you initialize them looks incorrect, you only initialized k.
for(;gets(str);)
{
int temp=0;
int i,j,k;
for(i=0,j=0,k=0; str[k]!='\0'; k++){ if(str[k]!=' ')temp=temp*10+(str[k]-48);
And don't use gets, it's dangerous, use fgets instead.
This happens because your former code does not obey the C standard under which you compile the code. Check the manual of your C (or C++) compiler how to turn on (if possible) the compilation under the C99 standard. For GNU compiler it is -std=c99 switch.

Dynamic memory allocation on stack

I recently tried this experiment in which instead of going for dynamic memory allocation for memory requirements of unknown size, I did a static allocation. When an array a[i] was declared by me, I kept i (size of the array) variable and dependent on the input that the user gives.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
void function(int );
int main(void)
{
int i;
printf("Enter:");
scanf("%d",&i);
function(i);
printf("i = %d\n",i);
getch();
return 0;
}
void function(int i)
{
char a[i];
char b[4];
strncpy(a,"hello",i);
strcpy(b,"world");
int j = 0;
char *c = a;
for( j = 0; j< 20; j++ )
printf("%c",*c++);
}
My questions are:
Is such an operation legal?
If no, why does the compiler not issue any warning or error?
Where will this memory be allocated: Stack or heap?
Why does ANSI C/GCC allow this?
Is such an operation legal?
It's called a variable length array.
VLAs are legal in ANSI C99 and as an extension to some pre-C99 compilers. GCC supports it both as strict C99 and as an extension to non-C99 code. It's also legal in C++0x.
If no, why does the compiler not issue any warning or error?
With gcc:
$ gcc -std=c89 src/vla.c -Wall -ansi -pedantic
src/vla.c: In function ‘function’:, not dynamic array.
src/vla.c:17: warning: ISO C90 forbids variable length array ‘a’
src/vla.c:21: warning: ISO C90 forbids mixed declarations and code
The presence of 'conio.h' from MSDOS indicates you're probably using a Microsoft Visual C++ compiler, so don't worry about it. MS has worked to make their compiler more conformant to the C++0x standard, but makes no claims about how standard its C compiler mode is. You're asking why Spanish dialect words aren't in the French dictionary.
Where will this memory be allocated: Stack or heap?
It is an automatic object, so most C implementations will put in on the stack for efficiency reasons.
Why does ANSI C/GCC allow this
It is useful for creating temporary arrays of variable size at runtime whose lifetime doesn't extend beyond the function call.
This is valid C99.
Look here for a more detailed explanation in another StackOverflow question.
This is legal, but not all compilers support it. At least Visual Studio <= 2003 afaik do not support it.
I would assume it is not Ansi C++, try gcc -ansi -pedantic.
Variable length arrays are illegal in ANSI C (C89). Try upping your compiler's warning level and I'm sure you'll get a warning/error.
The code is valid, but there is one thing to keep in mind when using variable length arrays.
void function(int i)
{
int a[i];
.
.
}
There is no error checking here. This code can fail if i is too big.
Dynamic memory allocation on stack:
There is a library call _malloca which allocates memory dynamically on program stack (very much like malloc does on Heap)
Reference: _malloca

Resources