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.
Related
I'm new to c and I am having a hard time understanding why am I getting an error while trying to compile the following code in c I believe I tried it Java and it worked compiled perfectly without error
void f(void) {
int i;
i = 6;
int j;
j = 20;
}
In "old" C all declarations must be at the top of the functions. In later versions like C99, C declarations can be anywhere in the code. I guess you have an old compiler.
Change your code to
void f(void) {
int i;
int j;
i = 6;
j = 20;
}
The problem is that for some old compilers you need to declare the variables before any executable statement. If you do not want to have this problem, switch to a newer compiler.
If your compiler is configured to compile c code following c98 then you will get this error because following c98 standard the déclaration of variables must be done first then we can make assignment so we can't make declaration of variable in the middle of the code.
However you can select the option to compile your code following the standard c99 and in this case you can make the déclaration of variable in the middle of your code.
#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.
Folks I think I will throw all my modest C lore away. Look at this code:
int main(int argc, char** argv, char** envp)
{
int aa;
srand(time(NULL));
int Num = rand()%20;
int Vetor[Num];
for (aa = 0; aa < Num; aa++)
{
Vetor[aa] = rand()%40;
printf("Vetor [%d] = %d\n", aa, Vetor[aa]);
}
}
I would think that this should throw an error for two reasons - first that I am declaring both Num and Vetor after executing a command (srand), second because I am declaring Vetor based on Num, this should not be possible right? because those array sizes should not be decided at runtime but at compile time right?
I am really surprised that his works and if you guys could explain why I can actually use stuff like this would be great.
This is using GCC.
These are C99 features, and it seems your compiler supports them. That's all ;)
From Wikipedia:
C99 introduced several new features, many of which had already been implemented as extensions in several compilers:
inline functions
intermingled declarations and code, variable declaration no longer
restricted to file scope or the start
of a compound statement (block)
several new data types, including long long int, optional extended
integer types, an explicit boolean
data type, and a complex type to
represent complex numbers
variable-length arrays
support for one-line comments beginning with //, as in BCPL or C++
new library functions, such as snprintf
etc (more)
C99 supports declarations anywhere in the code, as well as VLAs. What compiler are you using?
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
Why does the following code compile with the Dev-C++ compiler and
not with Visual Studio?
Any idea? Here is the code:
#include<stdio.h>
main(){
int n,i;
scanf("%d",&n);
int arr[n];
for(i= 0 ; i <n ; i++)
{
//Do something with the array
}
fflush(stdin);
getchar();
}
Here are the errors:
Errors http://img688.imageshack.us/img688/6618/26863513.jpg
This:
int arr[n];
is invalid because n is not a constant expression. You need to allocate variable sized arrays on the heap using malloc (and then free them when you are done with free).
If you are trying to compile this with a .cpp extension, main must have a return type of int. If you are trying to compile this with a .c extension, then you need to use c-style local variable declaration and declare all of your local variables at the top of the function.
Visual C++ doesn't do stack allocations with that syntax (though I wish it did). You can do stack allocations explicitly with:
int *arr = (int *)_alloca(n*sizeof(*arr));
and no need to free it since it's automatically freed when the scope ends.
This isn’t valid C++ – the Visual C++ compiler does not contain an up-to-date C compiler (rather a C subset of C++) and in particular it doesn’t implement C99 or anything newer. Your code uses features that the Visual C++ compiler doesn’t know (int arr[n]).
To simplify the answers you have gotten:
Your code is C99 and Visual C++ only supports C89. Do yourself a favour and get a better compiler for Windows. The Intel compiler has much better support for C99 than the Microsoft compiler (which has none).
Your program is not a Standard compliant program.
Any standard compliant compiler is required to issue a diagnostic when attempting to compile it.
If Dev-C++ compiled it without a warning, the compiler was invoked in a non compliance mode.
Other than the required diagnostic, a compliant compiler can attempt to compile anyway or just plainly abort compilation.
main()
In C89 this is valid and requires no diagnostic, In C99 this is invalid and requires a diagnostic (valid C99 definitions are int main(void) or int main(int argc, char **argv) or equivalent) ... so if you are using a compliant compiler it is a C89 compiler.
scanf("%d",&n);
int arr[n];
Oops, this is invalid in C89. In C89 you cannot have code intermixed with declarations. A C89 compiler must issue a diagnostic when it sees the declaration of the array.
So ... you are using your compiler in a non-conforming way. There's no way to tell why it compiles or fails to compile.