I'm writing code in C that initializes a bunch of structures using parts of other structures. For example:
//Original structure
struct
{
int foo1;
int foo2;
int foo3;
} orig_struct = {1,2,3};
//New structure
struct
{
int bar1;
int bar2;
} new_struct = {orig_struct.foo1, orig_struct.foo2};
I have to do this for a lot of structures, and the initialization method above makes the code look very clean and readable. To be clear, I don't have any control over the original structures. I'm just creating the new structures to capture data from them.
I ran into an issue when one of the structures had a large array:
//Original structure
struct
{
int foo1;
int foo2[50];
int foo3;
} orig_struct = {1,{2,3,etc},52}; //<--replace "etc" with 48 more int values
//New structure
struct
{
int bar1;
int bar2[50];
} new_struct = {orig_struct.foo1, XXX};
Is there anything I can replace XXX with to initialize the array in the new structure with the values in the array of the original structure? Again, I'd like to keep a clean, consistent look to my code, so keeping it within the curly brackets would be ideal. I know I can manually type out each element of the array within their own curly brackets:
...
} new_struct = {orig_struct.foo1, {orig_struct.foo2[0],orig_struct.foo2[1],orig_struct.foo2[2],orig_struct.foo2[3],etc}
But it's pretty obvious why that can quickly become untenable.
Note that your syntax for initializing new_struct does not work if new_struct has static storage duration, since a constant expression is required in that case.
There really isn't any way to directly assign an array to another array. This is only allowed if the array itself is encapsulated by a structure, and you are using structure assignment. Since your original structure and new structure share a common initial prefix, you could try to exploit this through a union:
struct orig_struct_type orig_struct = {1,{2,3},52};
void some_function ()
{
union {
struct orig_struct_type o;
struct new_struct_type n;
} *u = (void *)&orig_struct;
struct new_struct_type new_struct = u->n;
/* ... */
}
If you are simply trying to reduce code duplication, you can place the array initializer list into a macro.
#define VALUES {2,3,etc} //<--replace "etc" with 48 more int
//Original structure
struct
{
int foo1;
int foo2[50];
int foo3;
} orig_struct = {1,VALUES,52};
void some_function ()
{
struct
{
int bar1;
int bar2[50];
} new_struct = {orig_struct.foo1, VALUES};
/* ... */
}
In c, I see no way to do this within an initializer, as assigning an array is not supported, and expressions must be constant expressions; so a loop or memcpy is not possible during initialization (cf. array initialization reference):
As with all other initialization, every expression in the initializer
list must be a constant expression when initializing arrays of static
or thread-local storage duration:
Later on, of course, you could write memcpy(new_struct.bar2, orig_struct.foo2, sizeof(new_struct.bar2)), but this code is then separated from the struct/variable declaration.
Related
I'm struggling for a few days now to find a solution to wrap a C struct containing multiple variable-sized int arrays (stored as pointers) in swig.
Suppose the following minimal example:
typedef struct {
size_t length;
int *a;
int *b;
} mystruct;
where both a and b are pointers to int arrays allocated somewhere in C. The size of both arrays is stored in the length member.
Now, what I would really like to have is two-fold:
access to a and b members in objects of type mystruct should be safe, i.e. exceptions should be thrown if index is out-of-bounds.
the data in a and b must not be copied-over into a python list or tuple but I want to provide __getitem__ methods instead. The reason for that is that the actual struct consists of many such arrays and they get really huge and I don't want to waste any memory by duplicating them.
I've seen examples how to accomplish this with fixed-sized arrays by writing wrapper classes and templates for each member that internally store the size/length of each array individually, e.g.: SWIG interfacing C library to Python (Creating 'iterable' Python data type from C 'sequence' struct) and SWIG/python array inside structure.
However, I assume once I would wrap a and b into a class to enable them to be extended with __getitem__ methods, I won't have access to the length member of mystruct, i.e. the 'container' of a and b.
One thing I tried without success was to write explicit _get and _set methods
typedef struct {
size_t length;
} mystruct;
%extend mystruct {
int *a;
};
%{
int *mystruct_a_get(mystruct *s) {
return mx->a;
}
int *mystruct_b_get(mystruct *s) {
return mx->b;
}
...
%}
But here, the entire arrays a and b would be returned without any control of the maximum index...
My target languages are Python and Perl 5, so I guess one could start writing complicated typemaps for each language. I've done that before for other wrappers and hope there is a more generic solution to my situation that involves only C++ wrapper classes and such.
Any help or idea is appreciated!
Edit for possible solution
So, I couldn't let it go and came up with the following (simplified) solution that more or less combines the solutions I already saw elsewhere. The idea was to redundantly store the array lengths for each of the wrapped arrays:
%{
/* wrapper for variable sized arrays */
typedef struct {
size_t length;
int *data;
} var_array_int;
/* convenience constructor for variable sized array wrapper */
var_array_int *
var_array_int_new(size_t length,
int *data)
{
var_array_int *a = (var_array_int *)malloc(sizeof(var_array_int));
a->length = length;
a->data = data;
return a;
}
/* actual structure I want to wrap */
typedef struct {
size_t length;
int *a;
int *b;
} mystruct;
%}
/* hide all struct members in scripting language */
typedef struct {} var_array_int;
typedef struct {} mystruct;
/* extend variable sized arrays with __len__ and __getitem__ */
%extend var_array_int {
size_t __len__() const {
return $self->length;
}
const int __getitem__(int i) const throw(std::out_of_range) {
if ((i < 0) ||
(i >= $self->length))
throw std::out_of_range("Index out of bounds");
return $self->data[i];
}
};
/* add read-only variable sized array members to container struct */
%extend mystruct {
var_array_int *const a;
var_array_int *const b;
};
/* implement explict _get() methods for the variable sized array members */
%{
var_array_int *
mystruct_a_get(mystruct *s)
{
return var_array_int_new(s->length, s->a);
}
var_array_int *
mystruct_b_get(mystruct *s)
{
return var_array_int_new(s->length, s->b);
}
%}
The above solution only provides read access to the variable sized arrays and does not include any NULL checks for the wrapped int * pointers. My actual solution of course does that and also makes use of templates to wrap variable sized arrays of different types. But I refrained from showing that here for the sake of clarity.
I wonder if there is an easier way to do the above. Also the solution only seems to work in Python so far. Implementing something similar for Perl 5 already gives me a headache.
So here is my problem.
I have a struct that has some properties:
struct foo {
const uint8_t propertyA;
int propertyB;
const int propertyC;
typeX propertyD;
typeY propertyE;
};
I then create an array of this struct since I have to represent multiple instances of the object foo:
const int foosQuantity = 8;
struct foo foos[foosQuantity] =
{{ .propertyA=0b11001100, .propertyB=0, .propertyC=140, ...},
{ .propertyA=0b11001000, .propertyB=0, .propertyC=150 ...},
//*** foosQuantity-3 MORE TIMES ***//
{ .propertyA=0b11001000, .propertyB=0, .propertyC=150 ...}}
Until now everything seems to work. However, I have not figured how to send an array of one type of property to a function. For example, I Have this function written in an extern library that takes an array of propertiesA:
void myFunc(const uint8_t *propertyAs, sizeArray){
//*** DO STUFF ***//
}
And I would like to send the properties of my struct directly without having to use a for loop that iterates through the struct array and copies the elements.
int main(){
//*** STUFF ***//
myFunc(foos.propertyA, foosQuantity);
//*** MORE STUFF ***//
return 0;
}
Is this possible?
If the entire struct array already exists in your program's memory, you aren't going to get more efficient than just passing a pointer to the start of the array, the array's length (in elements), and iterating on the propertyA members of the array:
void bar(struct foo *p, size_t len)
{
size_t i;
for(i = 0; i < len; i++)
{
dosomething(p[i].propertyA);
}
}
If you are restricted by assigned specifications to only be allowed to pass an array of propertyA (i.e. uint8_t) to your function, you do have to copy them out of the array of struct foo; there's no way around that.
This is not possible.
You can either
Use a parallel array with just propertyA that gets manipulated along side the array of foo.
Or create an array of propertyA then copy it back in the foo array.
Option 1 is the most memory efficient since it requires the least memory but it may require you to rewrite your a lot of your code.
Option 2 requires the least amount of rework of your code but requires more memory and time.
I got a question regarding to static member of structure
Here is the scenario:
Need 2d array variable to retain its values even after exited from the function in another C files. Subsequent call from main()-in another C file, to the function will use that last value and continue to do calculation to produce and update new values(retained also). So, I I think I need to use static for that array.
The 2D array is member of an 2D structure. I need 2D structure for identity purposes for the 2d array. Lets say I got identity[row][column] with member[5][5], I need statically define the member throughout the call from main(). But static for structure member is not allowed in C as I notice.
code i am trying on:
//in function.h
#define row 2
#define column 5
int function(int rowNUM);
//in function.c
int function(int rowNUM)
{
typedef struct {
static int member[5][5];
int y[5][5];
int forg;
} mystruct;
mystruct identity[row][column];// declare the identity as structure array
int columnNUM;
int c;
int d;
//----try to initialize member to 1
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
{
for(d=0;d<5;d++){
identity[rowNUM][columnNUM].member[c][d]=1;
}
}
}
//----try to update member--- The values should retain for subsequent call from main
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
{
for(d=0;d<5;d++){
identity[rowNUM][columnNUM].member[c][d]=1+identity[rowNUM][columnNUM].member[c][d]; // to update member new value
}
}
}
}
// in main.c
main()
{
function(1);
function(2);// member here is in different identity from function (1)
function(1);//member should retain its value from function(1)
function(2);//member should retain its value from function(2)
}
Any other suggestion is welcomed if this is not the way to achieve the goal.
I am quite new in programing Please help me on this.
You have defined a 2d array of structs, which is really hard to statically initialize because each struct contains matrices of ints. Also, you can't have only a member of a struct static, the whole structure has to be defined static.
The easiest way I can think of doing what you want is defining an static matrix of mystructs and a helper variable to initialize it just on the first call, ie,
//in function.c
#include <stdbool.h>
int function(int rowNUM)
{
typedef struct {
int member[5][5];
int y[5][5];
int forg;
} mystruct;
// helper flag
static bool first_call = true;
// this is a matrix of (row x cols) mystructs
static mystruct identity[row][col];
if (first_call) {
/* initialize the matrix however you want
BUT remember to set first_call to false!
*/
first_call = false;
}
// rest of function ...
}
If you don't want to keep the values of the y and forg members (what does forg stand for? is it a typo?), you should split the struct in two, but I can't see why would you want to keep some values of the struct and discard others unless they are temporal variables.
If y and forg are temporal varaibles, you should definitely split your struct definition in two.
Another way of doing that is passing the pointer to the matrix as a parameter to your function, so you can maintain state without using a static variable
int function(int rowNUM, mystruct **identity)
But note that, although most of the times arrays decay to pointers (you can find more information in similar questions to this one), they are not the same thing.
If you only want a member of the struct to be static, your best option will be to make a static type in the function, which in your case would be a static 2D array, and do the assignment to the [stack] structure when the function is called.
Eg:
.. function(...)
{
static int b[2][2]
typedef struct { int a[2][2] } struct1;
struct1 x[2][2];
x->a = b;
}
void function(int rowNUM){
int c;
int d;
int columnNUM;
typedef struct {
int member[3][3];
}mystruct;
mystruct identity[ROW][COLUMN];
static bool first_call = true;
if (first_call) {
// INTIALIZE each element of member array to 1
for (columnNUM=0;columnNUM<COLUMN;columnNUM++)//total cell
{
for (c=0;c<3;c++)
{
for(d=0;d<3;d++){
identity[rowNUM][columnNUM].member[c][d]=1;
//printf("identity[%d][%d].member[%d][%d]=%d\n",rowNUM,columnNUM,c,d,identity[rowNUM][columnNUM].member[c][d]);
}
}
}
first_call = false;
}
identity[0][0].member[0][0]=identity[0][0].member[0][0]+3;
printf("%d\n", identity[0][0].member[0][0]);
identity[0][0].member[0][1]=identity[0][0].member[0][1]+1;
printf("%d\n", identity[0][0].member[0][1]);
}
The above code produce:
first call= 4 2 second call= 7 3 third call= 10 4
Work perfectly fine,nice. But it works fine either I declare
mystruct identity[ROW][COLUMN];
or
static mystruct identity[ROW][COLUMN];
Does it mean I dont need to declare static at all?
I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes. This structure's definition needs to be global since I am going to use that type thereafter in my program. It is necessary to have a dynamic size for this structure because I will have a HUGE database populated by that type of variables in the end.
The code I have right now is:
struct user_defined_integer;
.
.
.
void def_type(int num_bits)
{
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
return;
}
(which is not working)
The closest thing to my question, I have found, is in here:
I need to make a global array in C with a size inputted by the user
(Which is not helpful)
Is there a way to do this, so that my structure is recognized in the whole file?
When doing:
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
You should get the warning:
warning: useless storage class specifier in empty declaration
because you have an empty declaration. extern does not apply to user_defined_integer, but rather the variable that comes after it. Secondly, this won't work anyway because a struct that contains a variable length array can't have any linkage.
error: object with variably modified type must have no linkage
Even so, variable length arrays allocate storage at the point of declaration. You should instead opt for dynamic memory.
#include <stdlib.h>
typedef struct
{
int num_bits;
int* val;
} user_defined_integer;
void set_val(user_defined_integer* udi, int num_bits)
{
udi->num_bits = num_bits;
udi->val = malloc(num_bits/sizeof(int));
}
What you need is a VLA member, as asked about here. Basically, you declare a struct with a size field and one element's worth of storage as last member, and over-allocate it.
Imported from that question :
typedef struct Bitmapset {
int nwords;
uint32 words[1];
} Bitmapset;
Bitmapset *allocate(int n) {
Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof *p->words);
p->nwords = n;
return p;
}
I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes.
This is not possible in C, because C types are a compile-time thing and don't exist at all at run-time.
However, with a C99 conforming compiler, you might use flexible array member. You'll need a struct containing some members and ending with an array without any given dimension, e.g.
struct my_flex_st {
unsigned size;
int arr[]; // of size elements
};
Here is a way to allocate it:
struct my_flex_st *make_flex(unsigned siz) {
struct my_flex_st* ptr
= malloc(sizeof(struct my_flex_st) + siz * sizeof(int));
if (!ptr) { perror("malloc my_flex_st"); exit(EXIT_FAILURE); };
ptr->size = siz;
memset (ptr->arr, 0, siz*sizeof(int));
return ptr;
}
Don't forget to free it once you don't use it anymore.
Of course, you'll need to use pointers in your code. If you really want to have a global variable, declare it as e.g.
extern struct my_flex_st* my_glob_ptr;
Try this method-
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
struct user_defined_integer
{
int *val;
}user_int;
void memory_allocate(int num_bit)
{
int result;
result = (num_bit+CHAR_BIT-1)/CHAR_BIT; // since 8 bit =1 byte
user_int.val=malloc(result*sizeof(int));
if(user_int.val == NULL){
printf("Failed to allocate memory\n");
return ;
}
else
printf("Allocated %d bytes for val\n",result);
}
int main()
{
int num_bit;
printf("Enter the number of bits\n");
scanf("%d",&num_bit);
memory_allocate(num_bit);
// do your stuff here
free(user_int.val); // free the memory at the end;
return 0;
}
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.