I have a question about the member variables of static struct in C language.
Someone said we can declare a static struct, but in C, struct do not have the static members like class in C++, what does this mean? If I declare a static struct, what is the status of the members variable? can some one help me on this?
Note that a static struct itself is different from a static member of a struct. While you can declare a static struct variable:
static struct MyStruct s;
you can't define a struct type with a static member:
struct MyStruct {
static int i; // <- compiler error
};
The reason for this is that in C, a struct is a type - declaring a type of which a member variable is always the same instance (i. e. static) for multiple instances of that type is simply nonsense. In C++, structs are in reality classes (they only differ in the default visibility scope of members), and in C++ the static keyword means something else in this case. It means a class method - but since C doesn't have classes and methods, this doesn't make sense and is invalid in C.
Lesson learned: C++ is not C.
static in C means:
There shall only be one instance of this variable in the program.
The variable should be valid throughout the whole duration of the program execution.
The variable shall be initialized before main() is executed. If the programmer initializes a variable explicitly, then it should be set to this value. Otherwise it should be set to zero.
The variable (or static function) shall only be accessible from the scope it is declared inside. If declared at file scope (global), then it is only accessible in the same .c file.
In C++, there is also one additional meaning:
A static member variable or member function shall only be allocated once, no matter how many instances of a class that are allocated.
I have a question about the member variables of static struct in C language.
Someone said we can declare a static struct
Correct/legal:
// (global scope)
static struct t_struct {
int a;
} THE_STATIC_VARIABLE;
but in C, struct do not have the static members like class in C++
// (global scope)
struct t_ill_struct {
static int a; // << ill-formed in C, but valid in C++
};
what does this mean? If I declare a static struct, what is the status of the members variable? can some one help me on this?
Using the above example, it means that THE_STATIC_VARIABLE will have static storage. The following are equivalent:
A
// (global scope)
static struct t_struct {
int a;
} THE_STATIC_VARIABLE;
B
// (global scope)
struct t_struct {
int a;
};
static struct t_struct THE_STATIC_VARIABLE;
That is to say, every translation which sees THE_STATIC_VARIABLE's definition will get its own copy.
If you want the same effect as a static C++ member, you will have to declare it in another scope -- outside of a struct's declaration:
// file.h
// (global scope)
struct t_struct {
int a;
};
extern struct t_struct THE_GLOBAL_VARIABLE;
// file.c
struct t_struct THE_GLOBAL_VARIABLE;
Now we really have exactly one, like in C++.
Related
First, from this:
static struct foo1 { //private struct, just for this file
int a;
};
int main (void) {
struct foo1 a = {10};
return 0;
}
question number 1
I will get warning:
warning: useless storage class specifier in empty declaration
};
What does it mean? Why is static "useless storage class specifier"? In other context (static local var in function, or global static, which I wanted to apply for the struct foo1, it would work).
question number 2
#include <stdbool.h>
static struct s_t{ //private struct (for this file only)
static bool is_there = false; // defaul (pre-defined) value for all instances
int value;
};
int main (void) {}
Why is not possible to have static, predefined value for all vars of type struct s_t in c? I just wanted to simulate the same functionality as is in function static local var -> preserve value across multiple calls, in that sense, I wanted have one member (bool is_there in this case) that preserve value across each var of type struct foo1 (instance of it). So why it is not possible?
question number 3
Also, can someone explain the error (in more general sense) from it:
error: expected specifier-qualifier-list before ‘static’
EDIT:
from comments, I do not really understand the concept of storage class, I know only from asm, there is data/text/bss segments, so does it mean static var has address in read-only part of memory? Or what is the concept of storage class in c related to asm?
Because static struct foo1 { ... is just a struct definition, not a variable. You should add static when you declare the instance of the struct. I prefer this style:
typedef struct {
int a;
}foo_t;
static foo_t a = {10};
Because C simply doesn't have static member variables like C++ does. In C, it's pretty useless to add storage- or type specifiers to a single struct member. Put it on the allocated variables instead.
TL;DR it's just not making any sense of your syntax since you can't have static there. Unless you are terribly interested about language grammar, there's nothing else to it.
static is a storage-class specifier and const etc are type qualifiers and int etc is a type specifier. The term specifier-qualifier list comes from formal C grammar of structs, which isn't terribly interesting to read unless you are making a compiler. When declaring a struct member you have two options (C17 6.7.2.1):
specifier-qualifier-list:
type-specifier specifier-qualifier-list(opt)
type-qualifier specifier-qualifier-list(opt)
static doesn't fit the bill of either, being a storage-class specifier, so the compiler is saying "what! this is not a specifier-qualifier list where I expected to find one, where is it?"
(And yeah it's recursive, so you can have multiple of type-specifier or type-qualifier such as const long const const int value;. Because C stands for Crazy.)
because struct is like a type or an object, when you declare a static member in C, it would be like:
static int a = 0;
In this case "int" is like the struct type you declared, so if you want to create a struct static member just do like this:
static s_t a;
static struct foo1 { //private struct, just for this file
int a;
};
The static declaration specifier only applies to object or function declarations, not type definitions. All you're doing in that statement is creating the struct foo1 type. Had you written something like
static struct foo1 {
int a;
} foo;
Then the object foo would be declared static.
If you declare the type within the .c file, it will only be visible within that .c file. The only way to make the type visible to multiple .c files is to declare it in a header and #include that header in each file that needs it.
Why is not possible to have static, predefined value for all vars of type struct s_t in c?
Because C struct types are simply not that sophisticated - they're just a way to define a data item with multiple attributes. The language doesn't provide any way to have members that are common across all instances of the type.
Remember that C is a product of the early 1970s and was originally developed to implement the Unix operating system - it was designed to be small, portable, and fast. A lot's been added to it over the last 40-some-odd years, but nothing that really changes the core philosophy of the language.
Well, its quite evident that you will get the warning. The reason is simple! You are trying to assign a Storage Class to the struct definition.
However, storage classes are applicable to variable declarations. Therefore, you are getting the prompt.
If you still wish to employ the static storage class, then you can do so with any variable, preferably, any instance of the structure.
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.
I would like to have a struct that functions like this:
struct
member 1 (every instance of the struct has its own value of this)
static member (every struct shares this member)
I am aware that the static keyword does not do this.
My question is, how can I mimic this behavior?
Could I create a member that is pointer to a global variable?
Is there some other better way to do this?
Unlike structs in C++ which can have static data members, C structs don't have such a construct.
Since this is a common value for anyone that may use it, just declare it as a global:
int my_struct_common_val = 42;
struct my_struct {
...
};
I have declared two different structures with same name foo, as one of them is declared as globally, and can be easily accessible by any function in program. But I have this second struct in main, which is locally declared.
Worst comes worst I need to access both of them in main? I did it by declaring struct variable with different names. But now the problem is I need to check size of structures... How should I get the size of local struct not a global one?
#include <stdio.h>
#include <stdlib.h>
struct foo {
char arr1[200];
int x_val;
int y_val;
float result;
};
struct foo globe_foo;
int main()
{
struct foo {
char c;
char arr[20];
int x;
};
struct foo my_foo;
globe_foo.x_val = 20;
printf("Globe foo x_val: %d\n",globe_foo.x_val);
printf("Size of struct foo is: %d\n",sizeof(struct foo));
//how to check size of global decleared stuct foo?
printf("Size of struct foo is: %d\n",sizeof(struct foo));
system("pause");
return 0;
}
Variables within block scope whose name is same as the global scope hides the global identifier
ISO C9899 in 6.2.1 says:
If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will be a strict subset of the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.
So here the global struct foo is hidden totally(as if its not there) if you just refer to the typename inside the main().
Suggestions : use different names or use variables with different names for these types or typedef the struct types.
Your printf("Size of struct foo is: %d\n",sizeof(struct foo)); will give the size of only local struct foo(28 or 25 depends).
Standard C does not provide any way to refer to an identifier (either object name or type name) that is hidden by a local declaration.
In this case, you can see the size of the global struct foo by using the size of the object, sizeof globe_foo.
GCC (and compilers supporting its extensions) provides a way to refer to the type of an object, __typeof__. So, in GCC, you can refer to the type of globe_foo with __typeof__(struct globe_foo).
Another option is to give the global type an alias, with typedef. If, at file scope, you declare typedef struct foo foo_t;, then the type foo_t will be visible inside a function even when struct foo is hidden.
When printing sizes (values of type size_t), you should use a %zu specification with printf, not %d.
This question already has answers here:
Closed 13 years ago.
Possible Duplicates:
What does “static” mean in a C program?
Static vs global
What does "static" mean in C, giving the following example: "static struct ........"?
And what is the diffrence between this and "struct ......" without the "static"?
Outside a function, static makes whatever it's applied to have file scope. For example:
int a_function(int x) { ... }
This function will have global linkage, and can be accessed by any other object file. You just have to declare it to use it, as is usually done in a header file:
int a_function(int x);
However, if you use static in the definition, then the function is visible only to the source file where it is defined:
static int a_function(int x) { ... }
In that case, other object files can't access this function. The same applies to variables:
static int x;
This makes x a global variable, visible only within it's source file. A "static struct" by itself doesn't do anything, but consider this syntax:
struct {
int x;
int y;
} p1, p2;
This declares two global variables (p1 and p2), each of an "anonymous" struct type. If you append static:
static struct {
int x;
int y;
} p1, p2;
Then static applies to p1 and p2, making them visible only within their source file.
static tells that a function or data element is only known within the scope of the
current compile.
In addition, if you use the static keyword with a variable that is local to a function, it allows the last value of the variable to be preserved between successive calls to that function.
So if you say:
static struct ...
in a source file no other source files could use the struct type. Not even with an extern declaration. But if you say:
struct ...
then other source files could access it via an extern declaration.
I'm not a C programmer, but if static in C means anything like it does in other languages I use STATIC STRUC, meaning that the structure is common amongst all instances of this class.
Say I had a class variable called Z. The usual behaviour is that the value of this variable is specific to a particular instance of a classs, but when it is static, all instances of the class share the same value of Z at all times.
I don't know how this applies to C, isn't C object-less?