Referencing a struct within a struct - c

I have a C struct generated by an external tool. It looks like this:
typedef struct externalStruct{
int msgID;
struct internalStruct {
long someValue;
} *internalStruct ;
} externalStruct_t;
Do the following leaves internalStruct pointed to some random value on the heap:
externalStruct_t* newExternalStruct = new externalStruct_t;
So here's my question:
How do I properly instantiate the pointer "internalStruct"?

Here is how you can do it in C (C99 demo):
externalStruct_t* newExternalStruct = malloc(sizeof(externalStruct_t));
newExternalStruct->internalStruct = malloc(sizeof(*newExternalStruct->internalStruct));
In C++ you would need to insert casts (C++ demo):
externalStruct_t* newExternalStruct = new externalStruct_t;
// You need to rename internalStruct to internalStructType
// to avoid a naming collision:
newExternalStruct->internalStruct = new externalStruct::internalStructType;

Related

syntax confusion with creating a new struct type

struct I2C_CALLBACK_STRUCT
{
HANDLE (*I2C_OpenDevice)(UINT32 port, UINT32 freq);
BOOLEAN (*I2C_CloseDevice)(HANDLE handle);
};
typedef struct I2C_CALLBACK_STRUCT I2C_CALLBACKS_T, *I2C_CALLBACKS_PTR;
static const I2C_CALLBACKS_T I2C_Callback =
{
OpenI2CPort,
CloseI2CPort,
};
Could someone step through the above code and explain what is happening? I understand filling a struct with function pointers, but I don't understand what happens when you use the typedef to create the new types I2C_CALLBACKS_T and *I2C_CALLBACKS_PTR. Also I don't understand the syntax used when creating I2C_Callback ie. why is an equals sign used, as that is not something I am familiar with
I apologise for rambling on, I'm not sure of the best way to word my query.
1) typedef
What you are doing with typedef is creating two new types, I2C_CALLBACKS_T and I2C_CALLBACKS_PTR. You do this so you don't have to write struct keyword before defining your structure:
I2C_CALLBACKS_T a; // shorter
struct I2C_CALLBACK_STRUCT a; //longer
The type I2C_CALLBACKS_PTR is useful because you don't have to explicitly define pointers to structure:
I2C_CALLBACKS_PTR a, b, c; // shorter
I2C_CALLBACKS_T *a, *b, *c; // longer
2) Structure initialization
Then, I2C_Callback struct's function pointers just gets mapped to OpenI2CPort and CloseI2CPort functions.
maybe it would be clearer, if you remove all the "garbage" characters like:
// structure decalaration
struct callback
{
FUNCPTR1 function1;
FUNCPTR2 function2;
};
// getting rid of always typing `struct` and using a more convenient name
typedef struct callback CALLBACK;
typedef struct callback *CALLBACKPTR; // this one is bad behaviour if used, disturbing the reader of your code
// defining a callback-variable with initialization
CALLBACK c = {fun1, fun2};
// the same:
struct callback c = {fun1, fun2};
// which is, more-or-less, equivalent to: (if it is used inside a scope of afunction):
struct callback c;
c.function1 = fun1;
c.function2 = fun2;
the equal-sign is to be read as an assignment-sign.

multiple types in struct - C

I am new to C, and I am used to Java OOP. I have to use struct as holder for my global variables, that the system will write to/read from constantly.
I have 3 different types of variables in the struct, and I am not sure if that can cause a problem.
Also - do I need to declare the struct in the header file, in order to use it other C file ?
What will be the fastest and better way to access the variables from that struct in the different functions ? // The functions using these variables are in the same C file.
Here is the struct itself, that I made:
struct Data
{
double percentage_Height = 0;
double speed_Height = 0;
double time_Height = 0;
int distance_Height = 0;
double percentage_Distance = 0;
double speed_Distance = 0;
double time_Distance = 0;
int distance_Distance = 0;
uint16_t valueSpeed = 0;
double speedOfMotor = 0;
int tilt = 0;
};
and an example of a function that should use some of the fields of the struct:
int getHeight()
{
percentage_Height = getIncline()/90.0;
speed_Height = db_speed_sensor();
time_Height = 0.000027; // [h] , 100ms
distance_Height=0;
if (percentage_Height == 0)
{
percentage_Height = 1;
}
distance_Height = speed_Height * time_Height * percentage_Height * 100;
return distance_Height;
}
so what will be the best way to access these struct fields, instead of writing just the global vars?
EDIT: it is a real-time operating system, so tasks (smth like threads) will be accessing the data in the struct. I don't know if that makes any changes...
Define a global variable of type Data and access its members wherever you want.
struct Data GlobalData;
int getHeight()
{
GlobalData.percentage_Height = getIncline()/90.0;
GlobalData.speed_Height = db_speed_sensor();
....
}
If you want to use this in multiple files, better to define the structure in header file.
You have to declare the structure in a header file.
If an instance of this structure will be in the global scope, you have to define this instance in the global scope like this:
struct Data gData;
int getHeight()
{
gData.percentage_Height = getIncline()/90.0;
...
}
If your instance will be used only in the functions which are declared in the same file, you should define your variable like this:
static struct Data gData;
int getHeight()
{
gData.percentage_Height = getIncline()/90.0;
...
}
The keyword "static" means your variable is in the file scope (only visible in the file)
Yes, you should define the struct in a file and need to include it for its usage in other files. different datatypes in structure won't have any issue.
You can define functions separately to access the structure members and to process it. so that you don't need to repeat code. [ as like you did getHeight() ]. you can define those functions *inline*
to improve performance. (fastest way to access?) [only if the function is simple and (small in size)]
even you can use MACROS.
Use typedef for convenience.
typedef struct { ... } DATA;
so that code can be simplified. instead of writting
struct Data *s; simply put DATA *s;
you should use
s->structmember to process it.
Everyone has advised you to use a global structure. I would just like to add that, as you mentioned, all the functions accessing this structure are in one file, you should also declare a structure as static so that global structure will be limited file scope.
What will be the fastest and better way to access the variables from that struct in the different functions ? // The functions using these variables are in the same C file.
Using a pointer to that struct.
Example:
int getHeight(struct Data *data)
{
data->percentage_Height = getIncline()/90.0;
data->speed_Height = db_speed_sensor();
data->time_Height = 0.000027; // [h] , 100ms
data->distance_Height=0;
if (data->percentage_Height == 0)
{
data->percentage_Height = 1;
}
data->distance_Height = data->speed_Height * data->time_Height * data->percentage_Height * 100;
return data->distance_Height;
}
int main(int argc, char *argv[])
{
struct Data data;
load_data(&data); // function to initialize data
distance_Height = getHeight(&data);
return distance_Height;
}
Let the compiler decides when to inline those functions to improve performance, you should be worried about the readability and organization of your code.
Also - do I need to declare the struct in the header file, in order to use it other C file ?
If you want to direct access its members in other sources, you need to define it in a header, but you could just declare that you have that struct in you C, and create function to access the values of you struct. In this case you could define the struct only in the source file, and declare it in a header or any other source files you need this declaration.
Example:
file1:
#include <stdlib.h>
struct my_struct_s {
int value;
};
struct my_struct_s *create_my_struct(void)
{
return malloc(sizeof(struct my_struct_s));
}
void destroy_my_struct(struct my_struct_s *my_struct)
{
free(my_struct);
}
void set_my_struct(struct my_struct_s *my_struct, int value)
{
my_struct->value = value;
}
int get_my_struct(struct my_struct_s *my_struct)
{
return my_struct->value;
}
file 2:
#include <stdio.h>
#include <string.h>
struct my_struct_s;
struct my_struct_s *create_my_struct(void);
void destroy_my_struct(struct my_struct_s *my_struct);
void set_my_struct(struct my_struct_s *my_struct, int value);
int get_my_struct(struct my_struct_s *my_struct);
int main() {
struct my_struct_s *my_struct;
my_struct = create_my_struct();
set_my_struct(my_struct, 10);
printf("my_struct value = %d\n", get_my_struct(my_struct));
destroy_my_struct(my_struct);
return 0;
}
It would be better to have a header with the declarations needed to access the struct of file1, and include this header in file2, just made it this way to show you that it is possible, and maybe give you a clue about the difference between definition and declaration
A struct can hold any variety of types, no problem with how many variables you have in there as long as you have the memory for them.
You can declare a struct in a header file, but you will need to initialise it somewhere.
For example if you initialise it in a source file that is not your main and you still want to use it there, you will have to declare it in the main file with the keyword extern. Let me demonstrate:
file.h - a struct Foo is defined here
file.c - an instance of Foo named foo is initialised here with some values.
main.c - we want to use it here. In order to do that we put a statement for example right after the includes that reads extern struct Foo foo;
Or you can plain add file.h to your main.c file and just initialise it there.
Normally a struct variable is accessed like this: name_of_struct.member, e.g. struct.int_member = 42.
If you have a pointer to a struct and you try to modify the struct via the pointer there are two ways of doing this:
The more popular way:
ptr_to_struct->member = 42;
Or a more typical way for other types, but rather unusual in this case (at least for one level of dereference):
*ptr_to_struct.member = 42;
I would recommend that you pass the struct as an argument to the functions modifying it. Don't just use it as a plain global.

Typedef of structs

I am using structs in my project in this way:
typedef struct
{
int str1_val1;
int str1_val2;
} struct1;
and
typedef struct
{
int str2_val1;
int str2_val2;
struct1* str2_val3;
} struct2;
Is it possible that I hack this definition in a way, that I would use only types with my code, like
struct2* a;
a = (struct2*) malloc(sizeof(struct2));
without using keyword struct?
Yes, as follows:
struct _struct1
{
...
};
typedef struct _struct1 struct1;
struct _struct2
{
...
};
typedef struct _struct2 struct2;
...
struct2 *a;
a = (struct2*)malloc(sizeof(struct2));
Yes, you can use the typedef'ed symbol without needing the struct keyword. The compiler simply uses that name as an alias for the structure you defined earlier.
One note on your example, malloc returns a pointer to memory. Hence your statement should read
a = (struct2 *)malloc(sizeof(struct2));
Just to share, I've seen this approach, and though I personally don't like it (I like everything named and tagged =P and I don't like using variable names in malloc), someone may.
typedef struct {
...
} *some_t;
int main() {
some_t var = (some_t) malloc(sizeof(*var));
}
as a footnote. If you code in C++ then you don't need to do the typedef; a struct is a type automatically.

Constructor for structs in C

Given:
struct objStruct {
int id;
int value;
};
typedef struct objStruct Object;
Is there a shortcut to allocate and initialize the object, something like a C++ constructor?
It could even be a preprocessor macro. Whatever makes the code shorter and more readable than this:
Object *newObj = malloc(sizeof(Object));
// successful allocation test snipped
newObj->id = id++;
newObj->value = myValue;
In C I typically create a function in the style of a constructor which does this. For example (error checking omitted for brevity)
Object* Object_new(int id, int value) {
Object* p = malloc(sizeof(Object));
p->id = id;
p->value = value;
return p;
}
...
Object* p1 = Object_new(id++, myValue);
In C99 and beyond, you can use a compound literal, which looks like a cast followed by an initializer in braces:
int init_value = ...;
int init_id = ...;
Object newObj1 = (Object){ .value = init_value, .id = init_id };
Object newObj2 = (Object){ .id = init_id, .value = init_value };
The latter two lines achieve the same effect - the order of the fields is not critical. That is using 'designated initializers', another C99 feature. You can create a compound literal without using designated initializers.
In C it is possible to declare an inline function with the same name as structure:
struct my
{
int a;
};
inline struct my* my(int* a)
{
return (struct my*)(a);
}
//somewhere in code
int num = 123;
struct my *sample = my(&num);
//somewhere in code
It looks pretty similar to C++ ctors.
struct thingy {
char * label;
int x;
};
#define declare_thingy( name, label, val) struct thingy name = { label, val }
struct thingy * new_thingy(const char * label, int val) {
struct thingy * p = malloc(sizeof(struct thingy));
if (p) {
p->label = label;
p->val = val;
}
return p;
}
You really have to distinguish initialization of static or auto variables and dynamic allocation on the head. For the first, do named initializers, for the second a well specified init function.
All that can be nicely
packed into macros do give you an easy static/auto intialization and something similar to new in C++.
If you are looking for an object oriented "emulation" over C, I strongly recommend the GObject Type System [1], it's mature and largely used by GTK for instance.
GLib [2] has also a nice slice allocator for small objects, currently used by GNOME.
[1] GObject Reference Manual
[2] GLib Memory Slices

C Struct initialization : strange way

While reading a code I came across, the following definition and initialization of a struct:
// header file
struct foo{
char* name;
int value;
};
//Implementation file
struct foo fooElmnt __foo;
// some code using fooElmnt
struct foo fooElmnt __foo = {
.name = "NAME";
.value = some_value;
}
What does this mean in C and how is it different from usual declarations?
It's called designated initialization,
In a structure initializer, specify
the name of a field to initialize with
.fieldname = before the element
value. For example, given the
following structure,
struct point { int x, y; };
the following initialization
struct point p = { .y = yvalue, .x = xvalue };
is equivalent to
struct point p = { xvalue, yvalue };
If you read on, it explains that .fieldname is called a designator.
UPDATE: I'm no C99 expert, but I couldn't compile the code. Here's the changes I had to make:
// header file
struct foo{
char* name;
int value;
};
//Implementation file
//struct foo fooElmnt __foo;
// some code using fooElmnt
struct foo fooElmnt = {
.name = "NAME",
.value = 123
};
Were you able to compile it? I used TCC.
Those are designated initializers, introduced in c99. You can read more here
Without them, you'd use
struct foo fooElmnt __foo = {
"NAME",
some_value
};
While in this case it doesn't matter much - other than the c99 way is more verbose, and its easier to read which element is initialized to what.
It does help if your struct has a lot of members and you only need to initialize a few of them to something other than zero.
This is a designated initialization. This also initializing the fields by their name, which is more readable than anomynous initialization when the structures are getting large. This has been introduced by the C99 standard.

Resources