I was just wondering if a variable declared and defined inside a structure can be initialized to a certain value, was planning on using function pointers to mimic the classes in OOP.
Example COde:
typedef struct{
int x;
int (*manipulateX)(int) = &manipulateX;
}x = {0};
void main()
{
getch();
}
int manipulateX(int x)
{
x = x + 1;
return x;
}
Starting with C99, you can use designated initializers to set fields of structures to values, as follows:
struct MyStruct {
int x;
float f;
};
void test() {
struct MyStruct s = {.x=123, .f=456.789};
}
StructName s; // receives no initialization
StructName s = {x,y}; // value initializes all members
struct Child { StructName s; };
Child c; // receives no initialization
Child c = {x,y}; // value initializes all members
For Example :
struct Child{
int c;
int d;
}
Child childstruct ={10,20};
then childstruct.c will be 10
and childstruct.d will be 20.
http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc03strin.htm
One approach which I've used when programming an embedded system where memory was somewhat tight was to use some macros to both define a structure type and define its initial value. The definition looked something like:
#define CREATE_FOO_STRUCT \
X(int age, 34) Y \
X(int height, 65) Y \
X(char const * favoritecolor,"blue") Y \
X(int some_things[5],ARR5(1,2,3,4,5))
The ARR5 macro was needed to allow the initialization values for that array to be passed as a single parameter; an alternative would have been to write the last line as X(int some_things[5],{1 COMMA 2 COMMA 3 COMMA 4 COMMA5}). Given a macro like the above, it is possible to define X and Y so X returns expands to first item and Y to semicolon, in which case typedef {CREATE_FOO_STRUCT} FOO; will define structure FOO, and then redefine X and Y so that X returns the second item and Y a comma, in which case const FOO default_FOO = {CREATE_FOO_STRUCT}; will define a default instance. It's too bad I don't know any way to avoid the need to have either the last line differ from the others (the last line could match the others if each line but the first was preceded by X, and if the last line was followed by a //this line must be left blank line.
On the particular processor where I implemented the above constructs, defining default_FOO in that way would consume zero RAM, and consume ROM equal to the size of default_FOO. A function which would load a static instance of FOO with the default values, using conventional assignment statement, would consume four bytes of ROM for each non-zero byte in default_FOO, and would also require that there be a static instance it could use. A C-language function which would accept a FOO* and load the pointed-to instance with default values would take a monstrous amount of code (each assignment would have to separately compute the address of the data to be stored).
it is illegal to initialize a structure member inside the structure template in C, and is not permitted.. as a struct template doesnot hold any memory of its own, and all the members of struct are allocated a memory space only when they are associated with a struct type of variable, and since now they are allocated a memory they can be initialized.. but not before getting associated with a variable: e.g
struct tag_name
{
int x;
int y;
};
the above struct template doesnot hold a memory space.. unless a variable is associated to it as:
struct tag_name variable1;
now the struct type of variable variable1 will be allocated a memory which is large enough to hold two int values(for variable1.x and variable1. y)
and now only you can initialize the members x and y as e.g.:
variable1.x=10;
variable1.y=20;
and hence the following would be illegal
struct tag_name
{
int x=10;
int y=20;
};
Related
There are 2 struct definitions A and A. I know that there is OK to struct A contain a POINTER to struct A but I don't understand why struct A cannot contains struct A (not a pointer)
Because when you put structs inside each other, you're putting another copy of that struct into the struct at that point. For example:
struct A {
int q;
int w;
};
struct B {
int x;
struct A y;
int z;
};
This will be laid out in memory like this:
int /*B.*/x;
int /*A.*/q;
int /*A.*/w;
int /*B.*/z;
But if you try to put a struct inside itself:
struct A {
int x;
struct A y;
};
you have an A, which contains an int and another A, which contains an int and another A, and now you have an infinite number of ints.
Because in that case, it will take infinite storage as it will have to recursively store the data member of its own type. So, it is not possible. Whereas, Size of a pointer is fixed and hence causes no problem.
Let's suppose it could contain an object of its own type:
struct A_
{
A_ a;
int b;
} A;
What's sizeof(A) ? Answer: sizeof(A)+sizeof(int): impossible.
Because the structure definition is not finished until the closing curly-brace }. To declare a structure member the compiler need the full definition, as it uses that information to calculate things like space and padding and alignment etc. For a pointer to something the size of the pointer is the size of the pointer, and all the compiler needs os the name of the type, not its full definition.
Lets take a simple structure for example:
struct A // Here the compiler knows that there is a structure named A
// The compiler does not know its contents, nor its size
{
// Some members...
struct A *pointer_to_a; // All the compiler needs to know is the symbol A
// The size and alignment is that of a pointer
// and those are known by the compiler
// Some more members...
// struct A instance_of_A; // This is not possible! At this point the
// compiler doesn't have the full definition
// of the structure, and can therefore not
// know how much space it need to allocate
// for the member
// Some even more members...
}
// Now the compiler knows the full contents of the structure, its size
// and alignment requirements
;
When I declare structure given below, it is throwing compilation error.
typedef struct{
const char x; //it is throwing compilation error
const char y;
}A;
void main()
{
A *a1;
a1 = (A*)malloc(2);
}
How can I make structure's field (characters x and y) as constant?
That should be fine, but of course you can't assign to them, only use initialization.
So it doesn't make a lot of sense to allocate an instance on the heap.
This works:
#include <stdio.h>
int main(void) {
typedef struct {
const int x, y;
} A;
A my_a = { 12, 13 };
printf("x=%d\ny=%d\n", my_a.x, my_a.y);
return 0;
}
It prints:
x=12
y=13
Also, please don't cast the return value of malloc() in C.
First, you should use malloc to allocate the size of the struct, not a magic number 2. Also, don't cast malloc return value, it is automatically promoted to the compatible pointer type.
a1 = malloc(sizeof(A));
Second, there isn't really not much use to make struct member const.
A *a1;
a1 = malloc(sizeof(A));
a1's members are not initialized to any state here, yet the compiler forbidden any assignments to them, since it is defined as const, so a1->x = 'a'; won't compile.
A a2;
a2->x = 'a'; // won't compile too
The only valid use case is:
A a3 = {'a', 'b'};
You can't.
With POO in C you can disable the modification of those fields, if you:
define getters: char A_get_x(A *p); and char A_get_y(A *p);
define the struct in the .c to hide its implementation
only write typedef struct A A; in the .h file, to allow to use that type.
define a constructor : A *A_new(); which returns A with the values desired on x and y.
By doing this, you can only modify the values in the constructor, and after the object is created the values wont change (if you dont force the values with pointers etc..)
I want to declare a int num in struct S. Then the same struct should also have a array B of size num(So B will access num from it's own struct).
while in a function, I can do,
func(int A)
{
int max=A; //I could use A directly, I am just trying to explain my plan.
int B[max];
}
same won't work for struct as such,
struct S {
int num;
int data[num]; //this is wrong, num is undeclared
};
Is there any way I can do this?
Use a flexible array member:
struct S {
int num;
int data[];
};
int x = 42;
struct S *p = malloc(sizeof (struct S) + sizeof (int [x]));
p->num = x;
There are several problems with
struct S {
int num;
int data[num];
};
that cause it to not work the way you want to.
The first is that the num being used in the array member declaration isn't the same num that's the member of the struct type; the compiler treats the num in the array declaration as a regular identifier (i.e., it assumes there's a different variable named num in the same scope as the struct declaration)1.
The second problem is that a struct or union type may not have a variable-length array as a member2. However, the last member in the struct may have an incomplete array type:
struct S {
int num;
int data[];
};
Unfortunately, you're still kind of stuck here; if you create an instance of struct S like
struct S foo;
it doesn't actually allocate any space for the array. You'd need to allocate the struct dynamically:
/**
* Note that sizeof doesn't try to actually dereference foo below
*/
struct S *foo = malloc( sizeof *foo + N * sizeof *foo->arr );
to allocate space for the array itself. Note that you cannot declare an array of struct S or use it as a member of another structure or union type if the last member has an incomplete array type. 3
Honestly, your best option is to define the struct as
struct S {
size_t num;
int *data;
};
and then allocate the memory for data as a separate operation from allocating memory for the struct object itself:
struct S foo;
foo.num = some_value();
foo.data = malloc( sizeof *foo.data * foo.num );
Since struct S now has a known size, you can declare arrays of it, and you can use it as a member of another struct or union type:
struct S blah[10];
struct T {
struct S s;
...
};
1. C supports four different name spaces - label names (disambiguated by label syntax), struct/union/enum tag names (disambiguated by the presence of the struct, union, or enum keyword), struct and union member names (disambiguated by the . and -> component selection operators), and everything else. Since the num in your array declaration is not an operand of . or ->, the compiler treats it as a regular variable name.
2. 6.7.2.1/9: "A member of a structure or union may have any complete object type other than a variably modified type."
2. 6.2.7.1/3: A structure or union shall not contain a member with incomplete or function type (hence,
a structure shall not contain an instance of itself, but may contain a pointer to an instance
of itself), except that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union containing, possibly
recursively, a member that is such a structure) shall not be a member of a structure or an
element of an array.
First of all, the member num is not declared until the end of the struct definition, which ends at the last }.
Second, how would it make sense to set the array size to be the value of an uninitialized variable?
What I think you attempt to do with int B[max] is to create a variable length array (VLA). But that won't work either, as they are explicitly forbidden inside structs. 6.7.2.1/9:
A member of a structure or union may have any complete object type other than a
variably modified type.
What you could do instead is to declare a flexible array member, as demonstrated in the answer by Ouah.
The reason the compiler complains when you "flexibly declare" the array in the struct in global memory, is because global memory can only be allocated (declared) at compile-time and at compile time all sizes must be known. (The value of a variable is not known at compile time by definition.)
The reason it accepts a flexible array in a function, is because the function's local variables are created at the moment the function is entered and then the compiler can accept a variable size. (It boils down to the compiler allocating more memory on the stack and offsetting all accesses to local variables with the size - but different compilers could have a different approach.)
#include <stdio.h>
int size;
struct S {
int num;
int a[size]; // illegal: size must be known at compile time
};
int f(int size)
{
int a[size]; // legal as a is allocated on the stack
....
}
The following would be legal:
#include <stdio.h>
#define A_SIZE 10
struct S {
int num;
int a[A_SIZE]; // legal: A_SIZE is known at compile time
};
P.s.: I am not a C99 programmer; I may have some mistakes here.
Is it safe to return a struct with array data member in C?
Something like
struct my_str {
int v[5];
};
struct my_str ret_stupid() {
struct my_str rval;
/*do something..*/
return rval;
}
I don't know why... I'm a bit puzzled. (I've tried and it does work). Is there some standard explaining how this operation actually is performed? I mean the mechanism of struct return and assignment too could be useful to understand better.
Is it safe to return a struct with array data member in C?
Yes.
struct are copied bit-wise. Bit-wise copying a struct that has an array as a member makes sure that the copy of struct has a copy of the array too.
Structures are a lot like arrays.
They can contain variables of any kind.
Their addresses will be sorted stacked as long as you leave no gaps or invoke the preprocessor directive #pragma pack
"Is it safe", depends of the code hiding there..
/do something../
But in general - yes. This is just a function of type struct my_str and has to return struct my_str
What the structure contains - doesn't matter. Still safe to use.
You can return a structure from a function without any problems. It's a well-defined part of the language. You can pass structures to functions as well - a structure is exactly the same as any built-in type for purposes of parameter passing, return values, and assignment.
Here's an example
#include <stdio.h>
int func(int x)
{
int r = x;
return r;
}
int main(void)
{
int x = 12;
int y = func(x);
printf("%d\n", y);
return 0;
}
If it weren't for the array member, the return would be an "rvalue", a value that is just a copy of the value that you have inside the return expression. If you have
struct toto {
double a;
};
struct toto g(void) {
struct toto retval = { 0.0 };
...
return retval;
}
int main(void) {
printf("%g\n", g().a);
}
The argument of the printf call sees a copy of the variable retval that is used inside the function. g().a calls the function and uses the .a field of the return value.
This return value is and
entity that is not an object but only lives because of its "value", called rvalue in the C jargon. It only can be found on the RHS of an assignment, thus the "r" in "rvalue".
The case that you are giving is actually specially treated, because a "value" is not sufficient for all use cases of the array. So this generates a so-called "object with temporary lifetime". This is needed because if you'd do ret_stupid().v[2] the [] operator wants to have a pointer, and a pointer can only point to an object, not a value.
These objects only "live" inside the expression that contains the function call, and even though they are not const qualified you are not allowed to modify them.
So all in all, this is a corner case of C, and you shouldn't abuse it.
I'm trying to create structs with default values. I don't know how to accomplish this because every code that I see, is about initialising, and I would it for the natural way like...
struct stuff {
int stuff_a = 1;
int stuff_b = 2...
...and so on...
};
and looking about, I found this (C++) code:
struct a{ a() : i(0), j(0) {}; INT i; INT j;}
I never saw anything like this for C. Please, help me to understand it; I think that it is very nice!
UPDATE: Wait, I'm asking about C!!!! Why changed my question? If that is not possible in C just say... I don't know C++, I didn't know that was about C++...
If you want to set a struct object in one go and you have a C99 compiler, try this:
struct stuff {
int stuff_a;
int stuff_b;
// and so on...
};
struct stuff foo;
/* ... code ... */
foo = (struct stuff){.stuff_b = 42, .stuff_a = -1000};
Otherwise, with a C89 compiler, you have to set each member one by one:
foo.stuff_b = 42;
foo.stuff_a = -1000;
Running example # ideone : http://ideone.com/1QqCB
The original line
struct a{ a() : i(0), j(0) {} INT i; INT j;}
is a syntax error in C.
As you have probably learned from the other answers, in C you can't declare a structure and initialize it's members at the same time. These are different tasks and must be done separately.
There are a few options for initializing member variables of a struct. I'll show a couple of ways below. Right now, let's assume the following struct is defined in the beginning of the file:
struct stuff {
int stuff_a;
int stuff_b;
};
Then on your main() code, imagine that you want to declare a new variable of this type:
struct stuff custom_var;
This is the moment where you must initialize the structure. Seriously, I mean you really really must! Even if you don't want to assign specific values to them, you must at least initialize them to zero. This is mandatory because the OS doesn't guarantee that it will give you a clean memory space to run your application on. Therefore, always initialize your variables to some value (usually 0), including the other default types, such as char, int, float, double, etc...
One way to initialize our struct to zero is through memset():
memset(&custom_var, 0, sizeof(struct stuff));
Another is accessing each member individually:
custom_var.stuff_a = 0;
custom_var.stuff_b = 0;
A third option, which might confuse beginners is when they see the initialization of struct members being done at the moment of the declaration:
struct stuff custom_var = { 1, 2 };
The code above is equivalent to:
struct stuff custom_var;
custom_var.stuff_a = 1;
custom_var.stuff_b = 2;
... create structs with default values ...
That is impossible in C. A type cannot have default values. Objects of any type cannot have a default value other than 0, though they can be initialized to whatever is wanted.
The definition of a struct is a definition of a type, not of an object.
What you asking is about the same thing as a way to have ints default to, say, 42.
/* WRONG CODE -- THIS DOES NOT WORK */
typedef int int42 = 42;
int42 a;
printf("%d\n", a); /* print 42 */
Or, adapting to your example
/* WRONG CODE -- THIS DOES NOT WORK */
struct stuff {
int42 stuff_a;
int65536 stuff_b;
}
struct stuff a;
printf("%d\n", a.stuff_b); /* print 65536 */
Update: This answer assumes we 're talking about C++ because the code posted in the answer is not legal C.
struct a {
a() : i(0), j(0) {} // constructor with initialization list
int i;
int j;
}
The line marked with the comment is simply the constructor for instances of struct a (reminder: structs are just like classes, except that the default member visibility is public instead of private).
The part after the : is called an initialization list: it allows you to initialize the members of the struct with values (either constants or passed as constructor parameters). Initialization of members in this list happens before the body of the constructor is entered. It is preferable to initialize members of classes and structs this way, if at all possible.
See also C++: Constructor versus initializer list in struct/class.
in C (pre C99) the following also works:
#include <stdio.h>
typedef struct
{
int a;
int b;
int c;
} HELLO;
int main()
{
HELLO a = {1,2,3};
printf("here: %d %d %d\n",a.a,a.b,a.c);
exit(1);
}
See codepad
I'm not sure quite sure what your problem is. The standard way of initialising structures in c is like this:
struct a_struct my_struct = {1, 2};
Or the more recent and safer:
struct a_struct my_struct = {.i1 = 1, .i2 = 2};
If there is more than one instance of a structure, or it needs to be re-initialised, it is useful to define a constant structure with default values then assign that.
typedef struct a_struct {
int i1;
int i2;
} sa;
static const sa default_sa = {.i1 = 1, .i2 = 2};
static sa sa1 = default_sa;
static sa sa2 = default_sa;
// obviously you can do it dynamically as well
void use_temp_sa(void)
{
sa temp_sa = default_sa;
temp_sa.i2 = 3;
do_something_with(&temp_sa);
}
// And re-initialise
void reset_sa(sa *my_sa)
{
*my_sa = default_sa;
}
Type initializer is not possible in C.
A value must be stored in the memory.
A type does not occupy memory, what occupies memory is a variable of that type.
struct stuff; is a type; it does not occupy memory
struct stuff aStuff; is a variable of that type; aStuff occupies memory
Because a type does not occupy memory, it is not possible to save values into a type.
If there is syntactic sugar to support store/initialize values into a type then there must be additional code that is inserted to assign values to every instant variables of that type (e.g: in constructor in C++). This will result in a less efficient C if this feature is available.
How often do you need to retain this default values? I think it is unlikely. You can create a function to initialize variable with the default values or just initialize every fields with the values you want. So type initializer is not fundamental thing. C is about simplicity.
Can't initialize values within a structure definition.
I'd suggest:
typedef struct {
int stuff_a;
int stuff_b;
} stuff ;
int stuffInit(int a, int b, stuff *this){
this->stuff_a = a;
this->stuff_b = b;
return 0; /*or an error code, or sometimes '*this', per taste.*/
}
int main(void){
stuff myStuff;
stuffInit(1, 2, &myStuff);
/* dynamic is more commonly seen */
stuff *dynamicStuff;
dynamicStuff = malloc(sizeof(stuff)); /* 'new' stuff */
stuffInit(0, 0, dynamicStuff);
free(dynamicStuff); /* 'delete' stuff */
return 0;
}
Before the days of Object Oriented Programming (C++), we were taught "Abstract Data Types".
The discipline said 'never access your data structures directly, always create a function for it' But this was only enforced by the programmer, instructor, or senior developer, not the language.
Eventually, the structure definition(s) and corresponding functions end up in their own file & header, linked in later, further encapsulating the design.
But those days are gone and replaced with 'Class' and 'Constructor' OOP terminology.
"It's all the same, only the names have changed" - Bon Jovi.