Struct Scope Access - c

Hi this a continuation of a previous question I asked however I wasn't registered then and thus cannot edit the question. Anyways I have a struct
typedef struct
{
char input[100][100];
int count;
char name;
int startTime;
}INPUT;
extern INPUT *global;
this is within the header file. A stackoverflow member suggested that in my source file i use
INPUT global_[N], *global = global_;
to declare and initialise it which worked fine(as in I was able to store and print information out of the struct from within that method) however when I go to use the variable in other parts of my code it seems that the variable is out of scope?
I declare and use the variable global_ in a method called readFile and i'm trying to access the same information in main via *global.
Can this be done?
Thanks
Chee

extern INPUT *global;
This declares a global variable named global.
INPUT global_[N], *global = global_;
This defines an array global_ and a variable global. Depending on where this definition occurs (at function scope, or in a namespace, a class, or a function), global might or might not define the same object that's referred to by the declaration of global.

Related

use of static array to initialize constant struct object

I recently came across the following code:
static const struct gaih gaih[] = {
#if defined __UCLIBC_HAS_IPV6__
{ PF_INET6, gaih_inet },
#endif
{ PF_INET, gaih_inet },
#if 0
{ PF_LOCAL, gaih_local },
#endif
{ PF_UNSPEC, NULL }
};
struct gaih {
int family;
int (*gaih)(const char *name, const struct gaih_service *service,
const struct addrinfo *req, struct addrinfo **pai);
};
int func{
const struct gaih *g = gaih;
}
I understand the meaning of constant and static .
But I able to decipher the logic behind static initialization of the constant object in such a crude way.
please clarify the reason or use of doing it this way
file.c seems to be a C file. Using static in C has two meanings:
Not on the stack (e.g. for variables inside functions that shall keep their value across several calls of the function)
Not exported from this module (for variables that shall not be provided as a symbol to the linker)
In this case it seems to be the second one. The variable gaih shall not be exported (visible for the linker) static and it shall not be changed const. There is nothing crude.
But to clarify further details the complete valid code would be needed. It seems to be a constant and static initialisation of an array of structs with just one entry. The variable g is just a pointer to this single entry.
This example has some similarity with the struct gaih_addrtuple in nss.h which is a linked list of host names and IP addresses used for gethostbyname.
The global variable gaih is defined as static, which means it is only visible in the current file, and const, which means it can't be modified once initialized.
The local variable g is also defined as const, meaning it can't be changed. It is initialized with the address of the global gaih array, so g can be treated as an array in this context.
g can also be passed to another function, possibly in a different file. This allows the contents of gaih to be read outside of the current file which would not be allowed by attempting to reference gaih directly.

Is it bad practice to instantiate C struct object as global variable?

Here is an example code, struct A is declared and then it's instance "instanceOfA" is defined inside main, so it become local variable and to access it in other functions I should pass it as an argument. On the other hand struct B is declared and it's instance defined as global variable that allows me to use "instanceOfB" anywhere I need it, directly instead of passing it around as an argument. The only thing I should worry about now is that some function may overwrite "instanceOfA" identifier right? since it's variables (a,b,c) already in it's own "namespace". So is it a bad practice to define struct object as global variable? What would you do?
Sorry for my poor English.
struct A {
int a,b,c;
};
struct B {
int a,b,c;
} instanceOfB;
int main(void) {
struct A instanceOfA;
instanceOfA.a = 5;
instanceOfB.a = 10;
}
I'm not sure what is the question about exactly, but here are some thoughts.
instanceOfB is a global variable, right? So, it is an evil that should be avoided if not strictly necessary.
On the contrary, struct A instanceOfA; inside function body looks fine for me, though we usually move types from struct namespace to global namespace by using typedef struct idiom to reduce typing.
Yes, indeed, it is very bad practice to define anything as a global variable, not just a struct.
Yes, you will need to be passing it as a parameter. That's actually good, not bad.
It means that every single individual piece of code (function) in your program will only be able to modify what it is being given to modify, and not whatever it pleases.

Access of static variable from one file to another file

I recently came across the question like how to access a variable which declared static in file1.c to another file2.c?
Is it possible to access static variable?
My understanding about static keyword in C is,
static is "internal linkage", so they are accessible only from one compilation unit - the one where they were defined. Objects declared with internal linkage are private to single module.
As one of my friend suggest me below solution.
In file1.c
#include <stdio.h>
int main()
{
int b=foo();
printf("%d",b);
return 0;
}
in file2.c
static int a=25;
int foo()
{
return a;
}
compiled by gcc file1.c file2.c -o file
If I do above I can access the variable.
So my questions are:
Does the above program violate static variable rules?
If not, why is this so, and is there any other way to access static variable except including file (#include <…>) not like this.
How am I able to access a static variable from another file?
In C, how do I restrict the scope of a global variable to the file in which it's declared?
Correct me if I'm wrong with static variable concept and if any better solutions are available to access static variable?
1) does the above program violate static variable rules?
No you are not vailoting any rules. Here foo function create copy of value of that static variable and used in other file. Its fine.
2) If not why is this so, and is there any other way to access static variable except including file (#include<>) not like this How am I able to access a static variable from another file?
Static variable are only mean to use in that file only.
You can not use that variable making them extern in other files.
Another dirty hack is to get pointer of that static variable and make that as global pointer and making that as extern in another file you can use that static variable.
file1.c
#include<stdio.h>
static int a=25;
int* ptr = &a;
file2.c
#include<stdio.h>
extern int *ptr;
int main()
{
printf("%d",*ptr);
return 0;
}
Correct me if I'm wrong with static variable concept and if any better solutions are available?
A static variable has a lifetime extends across the entire run of the program
If you do not initialize static variable with some value then its default value would be 0.
A static variable has scope limited to its file only. You can not access it by name from a different file.
You have temp1.c and temp2.c both are getting compiled together then also you can have static variable of same name in both files — and they are separate variables.
In C, how do I restrict the scope of a global variable to the file in which it's declared?
By making that global variable as static.
What we commonly call a variable in C is actually two things: an object, the memory allocated for the variable interpreted with a certain type, and an identifier, one way to access that object.
There is no problem in accessing a static object or its value from another compilation unit. Your function foo promotes the value to another unit, that is fine, but it could even promote the address of a without problems.
Having internal linkage only concerns the identifer, the name a. This one is only visible inside file2.c.
With the static int a=25; the variable a will have internal linkage; meaning the linker cannot see a anywhere outside of the file2.c TU.
When you're calling foo() in file2.c, you get a copy of a, it's the copy that you print; but this doesn't mean you have access to the actual a defined in file2.c When you need such an access where the same variable is visible across different TUs, you could do this
Defining file
This file both declares and defines the variable; additionally initializes it to 1 too, without which it'll be default initialized to 0.
// (non-static) global variable with external linkage and thus visible across TUs
int var_across = 0;
void use()
{
var_across = 1;
}
Using file
// just a declaration to tell that it's defined elsewhere; not a definition
extern int var_across;
void use_here()
{
var_across = 2;
}
Assigning address of static variable to pointer will make static variable available to subfiles.
In subfiles we have to use extern keyword to the pointer.
But it is not necessary to do that.

Use of 'extern' Keyword [duplicate]

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 9 years ago.
i am confused in the use of extern keyword in C. when it is used with a variable, then it means the declaration of variable. I declare the variable tmp outside the main() function and define it in a separate block in main but when i print the value in subsequent block i got an error "UNRESOLVED EXTERNAL LINK". I am confused please give me detailed explanation.
#include <stdio.h>
extern int tmp ;
int main()
{
{
int tmp = 50;
}
{
printf("%d",tmp);
}
return 0;
}
No; extern int tmp; means "somewhere else there is a definition of the variable tmp"; this is a declaration — you can reference tmp but it is not defined. Further, when you write extern int tmp; outside a function, it means that the variable will be defined outside a function — it is a global variable which may be defined elsewhere in the current source file or in another source file. (The rules for extern int tmp; written inside a function are moderately complex; let's not go there now!)
Your local variable int tmp = 50; in the function is unrelated to the global variable tmp declared outside. The local variable hides the global variable inside the braces. (The local variable is also unused.) The printf() statement, though, references the global variable; the local variable is not in scope for the printf().
Because you do not define the global variable (for example, by adding int tmp = -2; at the bottom of the file), your program fails to link and will continue to do so until you either define the variable in this source file or link in another source file where the variable is defined.
This line :
extern int tmp ;
says look for the tmp variable definition elsewhere , which means look for the variable definition in other translation unit in the entire program.
when you define int tmp in main it is local to that function, i.e it doesn't have any external linkage.
Disclaimer- There are seriously many posts on SO regarding this like the one with link provided in the comments above . No, matter how much I add to this it will end up being a repetition. however , you have a good answer below by Jonathan leffler too.
Extern is redeclaration
, so it doesn't crate variable, but only tells compiler that real declaration is somewhere else.
You can use it in one source file to refer to variable declaration in another file, or in the same file to express that you use previously declared global variable.
So when you declare global variable
int a=5;
and use in function in the same source file, you can add extern int a; in the body of a function to clearly tell that it uses global variable but declaration is not here.
type func(arguments){
extern int a;
.
.
.
And when int a=5 is in another source file you place
extern int a;
in source file you actually want to use global variable a declared in previous source file.
This is about linkage. When you declare a variable extern you give it external linking, saying it's defined with global linkage somewhere else.
In your function you're defining a variable called tmp, but it doesn't have global linkage, it's a local variable. You'd have to define it outside of any function to give it global linkage.
There's also static linkage, which means a variable is global but only to the current compilation unit (source file).
Using the extern keyword you only declare the symbol tmp. Which means the symbols is defined somewhere else and will be resolved at link time.
So if you do not provide a compiled object defining the symbol, the linker gives you some kind of "unresolved symbol" error.
See the following question for more details on Declaration or Definition in C

C variables scope in struct

I've faced three separate situations in C lately that I would assistance on:
My C code has a global variable:
int ref_buf; //declared in a header file
In a function definition I use the same name as a parameter:
void fun(int ref_buf, param2, param3)
{
}
Will it overwrite the originally defined global variable and will it cause bugs?
Can I declare a static variable in a C data structure like so?:
struct my
{
int a;
static int b;
};
Does it work? Is there any specific situation where one would need it?
Can I initialize a individual structure variable as follows:
struct my
{
int a;
int b = 4;
};
Question 1
All references to ref_buf in that function will bind to the parameter and not the global variable.
Question 2
This is not legal in C but is legal in C++. The keyword static in C can only be used on file scope variables or on locals.
Question 3
No this is not legal in C (or C++). You will need to create a factory method to handle this.
my create_my() {
my m;
m.b = 4;
return m;
}
On Q3: GCC allows you to initialize a struct like this (as required by the C99 standard):
struct
{
int a;
int b;
} my = { .b = 4 };
GCC doc on designated initializers
1a) The local and global variables are separate entities, and so the local one won't overwrite the global. However, the global one won't be accessible inside the function (see also notes below).
1b) It not actually incorrect, but it is guaranteed to cause confusion, and confusion causes bugs, so it's best to use different names for each.
2) No, that's not legal C. You can however make the whole struct static.
3) No. You do it like this:
struct my
{
int a;
int b;
} = {0, 4};
Note 1: Variables should be declared in .c files, not .h files. If you need to make a variable accessible in multiple files, put an extern declaration in the header file.
Note 2: Avoid global variables if at all possible.
Question 1:
I think the variable declared in the local scope takes precidence, it shouldn't overwrite it but in the scope that the variable is declared it will be used instead.
That is assuming that it compiles.
On Q1:
Do not declare variables in a header file. If you include that header file in two source files and compile the source files together, you've got problems. Maybe your linker will get you out of them, maybe not.
If you really need global variables, and this happens a lot less than typical beginners think, put something like extern int ref_buf; in the header file, and int ref_buf; in a source file. That means there is one ref_buf, and all other source files will be able to find it.
The function parameter is essentially a new variable with the same name, and all references in the function will be to it. You will not be able to access the global variable from within that function. The function creates an inner scope, and variables declared in an inner scope are different from those in an outer one. This is potentially confusing, and makes it easy to create bugs, so having variables of the same name and different scopes is generally discouraged. (Variables of the same name in different struct definitions are usually not confusing, since you have to specify what struct contains the variable.)
The compiler will compile the function, but a good compiler will issue a warning message. If it refuses to compile because of one variable shadowing another of the same name, it isn't a real C compiler.
1) Local variables always take precedence e.g.
int ref = 10;
void fun(int ref)
{
printf("\n%d\n", ref);
}
int main()
{
fun(252);
return 0;
}
shows: 252
Qs 2 and 3 won't work in C.
Yes, it will technically overwrite, but a good compiler will warn you about this situation, and you will have "warnings = errors" on when you compile, so this won't actually compile.
Not needed, since the "my" struct is already declared as static, and it is therefore declared for the entire struct. This allocates the memory for the entire struct, so there is no need to say "take part of the struct which is already static and make it static".
No, not in the definition, but you can when you create an "instance", something like:
struct my MY =
{
{0, 4}
};

Resources