I am trying to share a global array between two files as below:
main.c:
#include <stdio.h>
#include "another.h"
int n=10;
int a[n];
void main(){
printf("Enter value:\n");
scanf("%d",&a[0]);
display();
}
another.h:
#include <stdio.h>
extern int n;
extern int a[n];
void display(){
printf("%d",a[0]);
return;
}
However, I am getting the following error:
variable modified 'a' at file scope
I'm not able to understand why I'm getting this error. Does anyone have an explanation?
The following appears to be an attempt at creating a variable length array. But regardless what it is actually, the 2nd of the following two lines is not legal:
extern int n;
extern int a[n];
n is not yet defined at the time it is used to create a.
In case you were thinking to create a VLA...
by definition VLAs are only created with automatic storage duration on the stack. This makes them unusable for use as extern or for any type of globally scoped variable.
However you can declare the size variable as an extern in a header file so that it is project global for any source file that includes that file, and once it is defined it can be used to size any array within project scope:
<some.h>
extern size_t array_size;
extern int gArray[100];
<some.c>
#include "some.h"
...
size_t array_size = 20;
int gArray[100] = {0};//Not a VLA
...
int main(void)
{
int array[array_size] = {0};
for(int i=0;i<sizeof(gArray);i++
{
//populate each element of gArray here
}
...
<someother.c>
#include "some.h"
int otherFunc(void)
{
//gArray is visible here just as it is in main(), with exactly the same values.
int local array[array_size] = {gArray[0],gArray[1],gArray[2],...,gArray[19]};
...
Related
I'm trying to use global variables to store 3 values from a file. When I run my project this is the error I get:
error: variably modified ‘pkt’ at file scope
error: variably modified ‘num’ at file scope
Here is my code:
config.h
#ifndef READCONFIG_CONFIG_H
#define READCONFIG_CONFIG_H
#include <stdio.h>
#define PATH "src/transferConfig.txt"
extern unsigned long int TIMEOUT_PKT;
extern int START_BUFFER_SIZE;
extern float PROBLOSS;
int getConfig(){
FILE *fp;
int n;
float p;
unsigned long int t;
if((fp = fopen(PATH,"rt")) != NULL) {
fscanf(fp, "N=%d\n p=%f\n T=%ld\n", &n, &p, &t);
fclose(fp);
TIMEOUT_PKT = t;
START_BUFFER_SIZE = n;
PROBLOSS = p;
}else{
TIMEOUT_PKT = 3000000;
START_BUFFER_SIZE = 15;
PROBLOSS = 0;
}
}
#endif //READCONFIG_CONFIG_H
window.h
typedef struct window{
packet* pkt[START_BUFFER_SIZE];
long num[START_BUFFER_SIZE];
}window
Error during the build
error: variably modified ‘pkt’ at file scope
error: variably modified ‘num’ at file scope
How can I fix this error?
START_BUFFER_SIZE is not known at the compile time, and it's not constant as you are able to assign a value to it. Variable size arrays require dynamic memory allocation. You need to know your array size in compile time to be able to use a static array.
First I code like this. but this get error.
#include <stdio.h>
int array[2][4]={1,2,3,4,5,8,9,0};
int (*p)[4]=NULL;
p=array;
int main(){
int j;
for(j=0;j<4;j++){
printf("%d",p[1][j]);
printf("\n");
}
return 0;
}
After that I modify my code like this.
I just put p=array; into int main()
#include <stdio.h>
int array[2][4]={1,2,3,4,5,8,9,0};
int (*p)[4]=NULL;
int main(){
p=array;
int j;
for(j=0;j<4;j++){
printf("%d",p[1][j]);
printf("\n");
}
return 0;
}
Why do they have different operation?
p=array; statement is an assignment statement and must be performed inside a function.
Here you declare and define global variable
int (*p)[4]=NULL;
Then you execute code (which is prohibited outside any function)
p=array;
Instead, you can do this
int (*p)[4]=array;
or explicitly declare and define like this
int (*p)[4];
int (*p)[4] = array;
p=array
is an assignment statement which cannot be performed outside an function.
As declaration should can be done anywhere inside a function (local declaration) or outside a function (global declaration) but assignment should be done inside a function only.
Though declaration and assignment at the same time can be done globally (like in your code):
int array[2][4]={1,2,3,4,5,8,9,0};
int (*p)[4]=NULL;
I just want to understand the difference in RAM allocation.
Why if i define a variable before function i have a RAM overflow and when i define it inside a function it is ok?
For example:
/*RAM OK*/
void Record(int16_t* current, int i,int n)
{
float Arr[NLOG2] = {0};
for(i=0;i<n;i++)
Arr[i]=current[i*5];
}
/*RAM OVERFLOW*/
static float Arr[NLOG2] = {0};
void Record(int16_t* current, int i,int n)
{
for(i=0;i<n;i++)
Arr[i]=current[i*5];
}
This is the message:
unable to allocate space for sections/blocks with a total estimated
minimum size of 0x330b bytes (max align 0x8) in
<[0x200000c8-0x200031ff]> (total uncommitted space 0x2f38).
The difference is that in the first case, Arr is declared on the stack; until the function is called, that array doesn't exist. The generated binary contains code for creating the array, but the array itself isn't in the binary.
In the second case, however, Arr is declared outside of any function (aka at file scope). Therefore, it always exists, and is stored in the binary. Because you appear to be working on an embedded platform, this otherwise insignificant difference causes your "RAM overflow" error.
In the 2nd case, the array is allocated when the application starts. It remains in the memory until the app quits.
In the 1st case, the array is only allocated when function void Record(int16_t* current, int i,int n) is called. The array is gone after the function finishes its execution.
static keyword doesn't have any impact if you have only a single compilation unit (.o file).
Global variables (not static) are there when you create the .o file available to the linker for use in other files. Therefore, if you have two files like this, you get name collision on a:
a.c:
#include <stdio.h>
int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
b.c:
int a;
int compute(void)
{
a = 0;
return a;
}
because the linker doesn't know which of the global as to use.
However, when you define static globals, you are telling the compiler to keep the variable only for that file and don't let the linker know about it. So if you add static (in the definition of a) to the two sample codes I wrote, you won't get name collisions simply because the linker doesn't even know there is an a in either of the files:
a.c:
#include <stdio.h>
static int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
b.c:
static int a;
int compute(void)
{
a = 0;
return a;
}
This means that each file works with its own a without knowing about the other ones.
this is the first code
#include <stdio.h>
void a();
int i;
int main()
{
printf("%d\n",i);
a();
return 0;
}
int i=5;
void a()
{
printf("%d\n",i);
}
output
5
5
the second code is
#include <stdio.h>
void a();
extern int i;
int main()
{
printf("%d\n",i);
a();
return 0;
}
int i=5;
void a()
{
printf("%d\n",i);
}
ouput
5
5
what is the difference between the codes if their outputs are same...
and if they are same then what is the use of extern
extern is something like saying to the Linker that you have defined the variable in some other file( even global variables can be made extern inside other functions in same file) don't throw error now you will find the variable later then link it .
using extern your only declaring the variable not defining it(no memory allocated).
In Your second program for first declartion
extern int i;
No memory is allocated but later when you declare
int i = 5 ;
the memory is allocated for i. while linker searches for i in printf if i is not declared extern it throws a error since its extern linking takes place when it finds the defintion of i.
extern means that you are declaring the variable but not defining it (allocating memory for it). Have a look at this link for a good explanation of extern: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I dont understand why this wouldn't work. Thanks!
#include<stdio.h>
#include<conio.h>
int main()
{
extern int i;
int i=20;
printf("%d",i);
}
Compilation results in the following error:
main.c: In function 'main':
main.c:6:9: error: declaration of 'i' with no linkage follows extern declaration
main.c:5:16: note: previous declaration of 'i' was here
Note: Code compiled online at CompileOnline
This won't work since you're trying to use i in two very different ways in the same scope.
The name i can't refer to both some extern data that someone else is defining, and a local variable.
If you just want to assign to the external variable, don't re-declare it:
extern int i;
i = 20;
You've already declared i as an int in
extern int i;
And then you go ahead and declare it again with
int i=20;
Try doing this instead
extern int i;
i=20;
You are mistakenly re declaring i
#include <stdio.h>
#include <conio.h>
int main()
{
extern int i;
i=20; //Simply assign the value here. why redeclare with `int`
printf("%d",i);
}
int i;
Here variable i is declared and memory is allocated for it but not initialized.
extern int i;
Whenever extern is used, the variable is just declared and memory will not be allocated for it. In order to access it you have to redeclare same variable externally.
Here extern refers to that, you will be defining the value of that variable(i) outside the program(external source). In your case, you do it inside so it will not work as you expected. It can be either defined outside main program or by external programs.
Try this:
#include<stdio.h>
int main()
{
extern int i; //Declared but memory not allocated
printf("%d",i);
return 0;
}
int i=20; //Allocated memory for i and initialized to 20 outside the prog
Output:
20
Global extern variables can also be initialized directly, where as local extern variables cannot be.
#include<stdio.h>
extern int i=10; //Declared, Memory allocated and defined.
int main()
{
extern int j; //Declared but memory not allocated
printf("%d --> %d",i,j);
return 0;
}
int j=20; //Memory Allocated and value defined externally.
Output:
10 --> 20
You can also refer to this link to know more about it.
you have declared i twice which resulted in redefinition error
extern indicates to the compiler that somewhere outside there exists a variable called i which is of type int.
Here, outside could be in the same program or in some other translation(another .c file) unit.
But you're redeclaring the same i which you already declared.
Also, if you're only executing the following program(without linking other files .c) it wont work:
#include <stdio.h>
#include <conio.h>
int main()
{
extern int i;
i=20;
printf("%d",i);
}
It gives a linker error complaining that i is unresolved because the linker was unable to find the definition for i and no storage was allocated to it as it is not defined outside the main.