Initializing fields of a structure - c

I'm working on a hash table assignment and I'm getting an unexpected error when trying to initialize my structure variables with a macro value. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symTable.h"
#define DEFAULT_TABLE_SIZE 61
#define HASH_MULTIPLIER 65599
typedef struct Node
{
char *key;
int *value;
struct Node *next;
} Node_T;
typedef struct SymTable
{
Node_T **Table;
int tablesize = DEFAULT_TABLE_SIZE; //where I am getting my error
int counter = 1;
} *SymTable_T;
and the error I am getting is
error: expected ':', ',', ';', '}' or '__attribute__' before '=' token
Can someone explain to me why it isn't accepting my macro value?

You try to initialize a member in a struct definition, which is a type1. That's no variable definition and doesn't take up any memory at runtime, mind you. You don't define any variable at all, so there's nothing to initialize.
When actually defining a variable you can do something similar by using a designated initializer list:
struct SymTable table = { .tablesize = DEFAULT_TABLE_SIZE, .counter = 1 };
This feature is only available since C99, however (GCC implements it as a non-conformant extension since C90!). Another, < C99 way, would be the somewhat bulkier
struct SymTable table = { NULL, DEFAULT_TABLE_SIZE, 1 };
where you need to know the order of members and the default values of each member.
1 Thanks to #M.M for that neat wording!

You are trying to use an assignment in the definition of struct SymTable. This is a structure, i.e. a kind of type. You can't assign a value to a type, or to a part of a type: a type isn't a piece of storage, it's a classification of storage.
You can use an assignment when defining an object of type struct SymTable. You can assign all the fields; if you omit some fields, the fields you omit will be initialized to “zero” (meaning 0 for integer fields, 0.0 for floating point fields, NULL for pointer fields).
struct SymTable syms1 = {NULL, DEFAULT_TABLE_SIZE, 1};
struct SymTable syms2 = {.counter = 1, .tablesize = DEFAULT_TABLE_SIZE};
The syntax I used for syms2 was introduced in C99, which is supported by most but not all common compilers). The syntax I used for syms1 has existed since the dawn of time; it has the downside that you need to provide values for the fields in order.
If you were trying to provide default values for any new object of type struct symTable, this is not a feature that C provides natively. A struct symTable declared by just writing struct symTable somename; in a function has uninitialized content, and there's nothing you can do about it. You can do it via a macro, but you'll need to call the macro explicitly when you create an object.
#define STRUCT_SYMTABLE_DEFAULT {NULL, DEFAULT_TABLE_SIZE, 1}
…
struct symTable syms3 = STRUCT_SYMTABLE_DEFAULT;
This approach has some downsides: you can only use this to initialize a struct, you can't use this syntax to assign a value later. Also, there's no type checking. A way to fix these defects is to return a value from a function. Good compilers will optimize it to the same code.
struct symTable inline symTable_default(void) {
struct symTable default = {NULL, DEFAULT_TABLE_SIZE, 1};
return default;
}
…
struct symTable syms4 = symTable_default();
…
/* Reset the table to its default value */
syms4 = symTable_default();

Related

C access enum from struct

My problem is that car_name_str could not be resolved. Why is it not callable and I want to keep the code structure?
I want to keep the structure as struct with union and enum (different datatypes).
Template: How can mixed data types (int, float, char, etc) be stored in an array?
//car_union.h
typedef struct {
enum { number_of_seats_int, car_cost_float, car_name_str } type;
union {
int number_of_seats;
float car_cost;
char* car_name;
} value;
}Car_data_ex[30][3];
extern Car_data_ex *Car_data[30][3];
//fill_car.c
#include "car_union.h"
Car_data_ex *Car_data[30][3];
Car_data[0][0]->type = car_name_str; //-> because pointer but doesnt work
Car_data[0][0]->value->car_name= "land rover";
Car_data[0][1]->type = car_cost_float; //doesnt work
Car_data[0][1]->value->car_cost= 45000;
Just remove the [30][3] from the type def, like this
#include <stdio.h>
//car_union.h
typedef struct {
enum { number_of_seats_int, car_cost_float, car_name_str } type;
union {
int number_of_seats;
float car_cost;
char* car_name;
} value;
}Car_data_ex;
extern Car_data_ex *Car_data[30][3];
int main() {
Car_data_ex *Car_data[30][3];
Car_data[0][0]->type = car_name_str; //-> because pointer but doesnt work
Car_data[0][0]->value.car_name= "land rover";
Car_data[0][1]->type = car_cost_float; //doesnt work
Car_data[0][1]->value.car_cost= 45000;
}
Regardless of what's in your struct, when you do
typedef struct Car_dataStructTag{
//...
}Car_data_ex[30][3];
(I've tagged the struct so it can be referred to by struct Car_dataStructTag),
then Car_data_ex is a type alias resolving to struct Car_dataStructTag [30][3]
which means
extern Car_data_ex *Car_data[30][3];
is fully equivalent to
extern struct Car_dataStructTag (*Car_data[30][3])[30][3];
which means Car_data[x][y] is a pointer to a two-dimensional array of struct Car_dataStructTag,
which is definitely not something you can apply -> to.
Try:
typedef struct Car_dataStructTag{
//...
}Car_data_ex[30][3];
extern Car_data_ex *Car_data[30][3];
extern struct Car_dataStructTag (*Car_data[30][3])[30][3];
in a compiler -- it gets accepted, confirming the declaration equivalence.
Running into situations such as this one is why it's generally considered ill-advisable to typedef arrays or pointers.
You have over complexified everything.
A typedef is just to give an alias to a (complex) type. Here the type is a struct containing an enum and an union. So it should be:
typedef struct {
enum { number_of_seats_int, car_cost_float, car_name_str } type;
union {
int number_of_seats;
float car_cost;
char* car_name;
} value;
}Car_data_ex;
Next, using an array of pointers can make sense, but provided each pointer in the array does point to a true object. Here you only want a plain (2D) array:
Car_data_ex Car_data[30][3];
Once this has been done, you can write with no error or warning:
Car_data[0][0].type = car_name_str;
Car_data[0][0].value.car_name= "land rover";
Car_data[0][1].type = car_cost_float;
Car_data[0][1].value.car_cost= 45000;
And you should avoid extern Car_data_ex Car_data[30][3];. It declares a global array, that will have to be defined in one single compilation unit (.c file). Here again, it can make sense, but IMHO it is a rather advanced feature that can be hard to correctly use. And nothing in the shown code lets think that is is required...

How to access enum defined within a struct in C program

I am new to the C language and struggling with how to access enum's within a struct.
My code is the following:
bankHeader.h File
struct bankAcct{
int amount;
enum typeOfAcc{chck = 0, saving = 1};
int balance;
}
bank.c File
#include <stdio.h>
#include "bankHeader.h"
struct bankAcct test;
test.amount=100;
// I want to be able to get the value within my typeOfAcc
// example something like test.typeOfAcct = "chck" should return 0;
I reviewed some of the forms but I dont see anything that was easy to understand or worked.
If the enum is meant to be local to the struct, use an anonymous enum:
struct bankAcct{
int amount;
enum {chck = 0, saving = 1} type_of_acct;
int balance;
};
You could also put a tagged enum inside the struct:
struct bankAcct{
int amount;
enum typeOfAcc {chck = 0, saving = 1} type_of_acct;
//^this misleadingly puts `enum typeOfAcc` in filescope
int balance;
};
but a tagged (as opposed to an anonymous one) inner definition of an enum (or struct or union) will be hoisted. In effect, the latter snippet is just a confusing way of doing:
enum typeOfAcc {chck = 0, saving = 1};
struct bankAcct{
int amount;
enum typeOfAcc type_of_acct;
int balance;
};
Note that as peter-reinstate-monica points out in his comment below, the chck and saving constants will be "hoisted" regardless of whether or not you choose to use an anonymous embedded enum type.
Every field in your struct declaration is in the form
type fieldName;
With
enum typeOfAcc{chck = 0, saving = 1};
you have specified the type... but not the field name. That's just like defining a structure in this way
struct foo {
int;
}
So, basically, what you need is a field name:
struct bankAcct{
int amount;
enum typeOfAcc{chck = 0, saving = 1} type;
int balance;
}
You will be able to access it with
struct bankAcct var;
printf("%d\n", var.type);
Addendum
I would not recommend defining an enumeration inside a struct, first of all for readability reasons. Another reason might be incompatibility with C++: I wasn't able to compile an example C++ code in which the symbols of the inner enum were accessed. The following assignment
struct bankAcct var;
var.type = chck;
raised an error on gpp because the symbol chck could not be referenced outside the struct definition scope. Even assigning an integer to the enum field lead the compiler to complain, and I could not even perform the casting
b.type = (enum typeOfAcc) 1;
because an error was raised: the enum typeOfAcc wasn't be accessible as well.
But in C these assignments would be ok, and both enum tags and constant identifiers (named and anonymous) would be "reachable". As explained in C specification 6.2.1§4, the scope of an identifier outside any code block is the whole translation unit:
Every other identifier has scope determined by the placement of its declaration (in a declarator or type specifier). If the declarator or type specifier that declares the identifier appears outside of any block or list of parameters, the identifier has file scope, which terminates at the end of the translation unit.
Just for completeness, after saying where the scope ends, we must say where the scope begins (C specification 6.2.1§7):
Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator.
You should declare the enum type outside the structure, then declare a member variable with that type.
typedef enum {
chck = 0,
saving = 1
} accountType;
struct bankAcct{
int amount;
accountType typeOfAcc ;
int balance;
}

Declaring a struct (that's already been typedef'd) within another struct?

My understanding of C is that there are two separate namespaces, one for tags (such as for structs) and one for all other variables (including structs). Using typedef before a struct definition will then treat the struct variable as a type, so if you use
struct car_part {/* Code Here */} CarPart;
(where CarPart is optional)
you'd have to use
struct car_part engine;
to declare a car part.
Whereas if you used a typedef with
typedef car_part {/* Code Here */} CarPart;
you can now use
CarPart engine;
instead.
typedef struct tag {/* Code here */} struct_name;
1) Is there any difference between declaring the actual variable before or after the block code? i.e.
typedef struct tag struct_name
{
/* Code here */
};
vs
typedef struct tag
{
/* Code here*/
} struct_name;
2) Are there ever any advantages to not using typedef for a struct definition, even if you won't declare another struct variable of that type?
3) The following code says that there's a syntax error C2061 with the identifier Node, but I don't see anything wrong with it. I tried adding the keyword struct before each element declaration, but that only gave more errors. Any thoughts?
typedef struct Ticket
{
char customer_name[20];
int ticket_number;
} Ticket;
typedef struct Node
{
Ticket ticket_info;
Node *next;
Node *previous;
} Node;
typedef struct Queue
{
Ticket *front;
Ticket *rear;
int queue_count;
} Queue;
edit: fixed first two lines of code to explicitly state where the element declarations should be.
There are actually four name-spaces in C (although this depends on a particular way of counting, and some include macro names as a fifth space, which I think is a valid way to think about them):
goto labels
tags (struct, union, and enum)
the actual members of a struct or union type (one per type, hence you could count this as "many" instead of "one" name space)
all other ("ordinary") identifiers, such as function and variable names and the names made to be synonyms for other types via typedef.
While it should (in theory) be possible to have separate spaces for struct vs union, for instance, C does not, so:
struct foo; union foo; /* ERROR */
is invalid. Yet:
struct foo { int a, b; };
struct bar { char b; double a; };
is just fine, showing that the members of the two different struct types are in different name-spaces (so again this makes the count of "4 name-spaces" above suspect :-) ).
All that aside, C has some moderately (and in some ways unnecessarily) complicated, but quite workable in practice, rules for how struct types work.
Each struct creates a new type unless it refers back to an existing type. The struct keyword may be followed by an identifier, or just an open brace {. If there is just an open brace, the struct creates a new type:
struct { ... } X; /* variable X has a unique type */
If there is an identifier, the compiler must look at the (single) tag name-space to see if that name is already defined. If not, the struct defines a new type:
struct blart { ... } X; /* variable X has type <struct newname>, a new type */
If the identifier is already present, generally this refers back to the existing type:
struct blart Y; /* variable Y has the same type as variable X */
There is one special exception, though. If you're in a new scope (such as at the beginning of a function), a "vacuous declaration"—the struct keyword, followed by an identifier, followed by a semicolon—"clears out" the previous visible type:
void func(void) {
struct blart; /* get rid of any existing "struct blart" */
struct blart { char *a; int b; } v;
Here v has a new type, even if struct blart was already defined outside func.
(This "vacuous declaration" trick is mostly useful in obfuscated code contests. :-) )
If you're not at a new scope, a vacuous declaration serves the purpose of declaring that the type exists. This is mainly useful to work around a different issue, which I will cover in a moment.
struct blart;
Here struct blart alerts you (and the compiler) that there is now a type named "struct blart". This type is merely declared, meaning that the struct type is "incomplete", if struct blart has not yet been defined. This type is defined (and "complete") if struct blart has been defined. So:
struct blart { double blartness; };
defines it, and then any earlier or later struct blarts refer to the same type.
Here's why this sort of declaration is useful. In C, any declaration of an identifier has scope. There are four possible scopes: "file", "block", "prototype", and "function". The last one (function scope) is exclusively for goto labels, so we can ignore it from here on. That leaves file, block, and prototype scopes. File scope is a technical term for what most people think of as "global", in contrast with "block scope" which is "local":
struct blart { double blartness } X; /* file scope */
void func(void) {
struct slart { int i; } v; /* block scope */
...
}
Here struct blart has file scope (as does "global" variable X), and struct slart has block scope (as does "local" variable v).
When the block ends, struct slart goes away. You can no longer refer to it by name; a later struct slart creates a new and different type, in exactly the same way that a later int v; creates a new v, and does not refer to the v within the block scope inside function func.
Alas, the committee that designed the original C standard included (for good reason) one more scope, inside the function prototype, in a way that interacts rather badly with these rules. If you write a function prototype:
void proto(char *name, int value);
the identifiers (name and value) disappear after the closing parenthesis, just as you'd expect—you wouldn't want this to create a block-scope variable called name. Unfortunately, the same happens with struct:
void proto2(struct ziggy *stardust);
The name stardust goes away, but so does struct ziggy. If struct ziggy did not appear earlier, that new, incomplete type that is created inside the prototype, has now been removed from all human reach. It can never be completed. Good C compilers print a warning here.
The solution is to declare the struct—whether complete or not [*]—before writing the prototype:
struct ziggy; /* hey compiler: "struct ziggy" has file scope */
void proto2(struct ziggy *stardust);
This time, struct ziggy has an already-existing, visible declaration to refer back to, so it uses the existing type.
[* In header files, for instance, you often don't know if the header that defines the struct has been included, but you can declare the struct yourself, and then define protoypes that use pointers to it.]
Now, as to typedef...
The typedef keyword is syntactically a storage-class specifier, like register and auto, but it acts quite weird. It sets a flag in the compiler that says: "change variable declarations into type-name aliases".
If you write:
typedef int TX, TY[3], *TZ;
the way that you (and the compiler) can understand this is to start by removing the typedef keyword. The result needs to be syntactically valid, and it is:
int TX, TY[3], *TZ;
This would declare three variables:
TX has type int
TY has type "array 3 of int"
TZ has type "pointer to int"
Now you (and the compiler) put the typedef back in, and change "has" to "is another name for":
TX is another name for type int
TY is another name for "array 3 of int"
TZ is another name for "pointer to int"
The typedef keyword works with struct types in exactly the same way. It's the struct keyword that creates the new type; then typedef changes the variable declaration(s) from "has type ..." to "is another name for type ...". So:
typedef struct ca ca_t;
starts by either creating new type, or referring back to existing type, struct ca as usual. Then, instead of declaring a variable ca_t as having type struct ca, it declares the name as another name for the type struct ca.
If you omit the struct tag name, you are left with only two valid syntactic patterns:
typedef struct; /* note: this is pointless */
or:
typedef struct { char *top_coat; int top_hat; } zz_t, *zz_p_t;
Here, struct { creates a new type (remember, we said this way back at the beginning!), and then after the closing }, the identifiers that would have declared variables, now make type-aliases. Again, the type was actually created by the struct keyword (although it hardly matters this time; the typedef-names are now the only ways to refer to the type).
(The reason the first pointless pattern is the way it is, is that without the braces, the first identifier you stick in is the struct-tag:
typedef struct tag; /* (still pointless) */
and thus you haven't omitted the tag after all!)
As for the last question, about the syntax error, the problem here is that C is designed as a "single pass" language, where you (and the compiler) never have to look very far forward to find out what something is. When you attempt something like this:
typedef struct list {
...
List *next; /* ERROR */
} List;
you've given the compiler too much to digest at once. It starts by (in effect) ignoring the typedef keyword except to set the flag that changes the way variables will be declared. This leaves you with:
struct list {
...
List *next; /* ERROR */
}
The name List is simply not yet available. The attempt to use List *next; does not work. Eventually the compiler would reach the "variable declaration" (and because the flag is set, change it to a type-alias instead), but it's too late by then; the error has already occurred.
The solution is the same as with function prototypes: you need a "forward declaration". The forward declaration will give you an incomplete type, until you finish defining the struct list part, but that's OK: C lets you use incomplete types in a number of positions, including when you want to declare a pointer, and including with typedef alias-creation. So:
typedef struct list List; /* incomplete type "struct list" */
struct list { /* begin completing "struct list" */
...
List *next; /* use incomplete "struct list", through the type-alias */
}; /* this "}" completes the type "struct list" */
This gains relatively little over just writing struct list everywhere (it saves a bit of typing, but so what? well, OK, some of us suffer a bit of carpal tunnel / RSI issues :-) ).
[Note: this last segment is going to cause controversy... it always does.]
In fact, if you mentally replace struct with type, C code becomes a whole lot nicer to "strongly typed language" fans. Instead of the terrible [%], weak-sauce:
typedef int distance; /* distance is measured in discrete units */
typedef double temperature; /* temperatures are fractional */
they can write:
#define TYPE struct
TYPE distance;
TYPE temperature;
These, being incomplete types, are truly opaque. To create or destroy or indeed do anything with a distance value you must call a function (and—for most variables anyway; there are some exceptions for external identifiers—use pointers, alas):
TYPE distance *x = new_distance(initial_value);
increase_distance(x, increment);
use_distance(x);
destroy_distance(x);
Nobody can write:
*x += 14; /* 3 inches in a dram, 14 ounces in a foot */
It simply won't compile.
Those who are a bit less bondage-and-discipline with their type systems can relax the constraints by completing the type:
TYPE distance { int v; };
TYPE temperature { double v; };
Of course, now "cheaters" can do:
TYPE distance x = { 0 };
x.v += 14; /* 735.5 watts in a horsepower */
(well, at least that last comment is correct).
[% Not really that terrible, I think. Some seem to disagree.]
1) The difference between those two blocks of code is that the first one is invalid syntax, while the second one is good and useful. I use the second one in order to define a struct and also define a typedef for the struct at the same time. My code has stuff that looks like this:
typedef struct Dog {
int age, barks;
} Dog;
After that line, I can define dogs with Dog mydog; or struct Dog mydog;.
It's important to understand that the code above is doing two things. It is defining a type named struct Dog, and then it is defining a type named Dog that just refers to struct Dog. You could split that into two separate steps like this:
struct Dog {
int age, barks;
};
typedef struct Dog Dog;
2) I always use the typedef as shown above in the first block of code and have found no problem with it. I would say there are no advantages to leaving out the typdef. Just for the record, if you want to leave out the typedef and only define a struct, then you code would be:
struct Dog {
int age, barks;
};
If you do it that way, you can only make new dogs by typing struct Dog mydog;; in other words, the name of the type is only struct Dog and Dog does not name a type.
3) The problem is that you are trying to use "Node" inside the definition of "Node". That would be a circular definition. You can fix everything by just writing it like this:
struct Node;
typedef struct Node
{
struct Node * next;
struct Node * previous;
} Node;
1) Your first example is invalid syntax. The correct way is this:
typedef struct tag {
/* ... */
} struct_name;
2) Using typedefs for structures makes them seem like atomic data types. It also allows for you to make the types opaque (so other code blocks can't see the inside of the structure). Personally, I find typedef-ing of structures to be a very bad habit (since the struct identifier helps differentiate structures and typedefs of atomic types).
3) You are trying to use the typedef'd version of the node structure inside itself! You need to use the struct Node identifier for the structure when defining it within itself. Like this:
typedef struct Node {
Ticket ticket_info;
struct Node *next;
struct Node *previous;
} Node;

Structs in C confusion

I have a c file that starts with a struct I am calling stringtable, looks like this
struct stringtable {
int table[];
int numElements = 15;
};
And I have a header for it that has this typedef
typedef stringtable *stringtable_ref;
When I compile with gcc I get the errors:
expected identifier or '(' before '[' token
expected ':' before 'int'
like I have declared the struct wrong. I have done structs in C like this before so my question is: Am I making a mistake declaring my struct? Does it need to have a tag before the semicolon? Are there only certain places I am allowed to declare a struct?
struct stringtable {
int table[];
int numElements = 15;
};
A flexible array member like int table[]; can only be the last member of a struct (with at least one more member).
And you can't assign a default value to a member in a struct declaration, C doesn't support that.
Unless you have a static member in your struct, you cannot initialize the members upon declaration.
You need to create an instance of your struct before initalizing the members:
struct stringtable str_table;
str_table.numElements = 15;
//etc
I would also expect that you need in the header typedef struct stringtable *stringtable_ref

Using structure in C and C++

I am new to C and I want to know how to access elements inside a structure which is placed inside a structure.
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char src[4];
unsigned char dst[4];
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
How to access elements inside profile_t??
struct profile_t;
The above statement doesn't create an object of type profile_t. What you need to do is -
struct profile_t inObj ;
Then create object for profile_datagram_t. i.e.,
header outObj ; // header typedef for profile_datagram_t
Now you can access elements like -
outObj.inObj.type = 'a' ; // As an example
In C++, while creation of object for a structure, struct key word isn't necessary.
On your question edit and comment :
struct profile_t profiles[MAXPROFILES];
profiles is an array of objects of type profile_t. To access the individual object, just use the [] operator. i.e.,
header obj ;
obj.profiles[0].type = 'a' ; // Example
obj.profiles[i], where i can take values from 0 to MAXPROFILES - 1, gives the object at index i.
Not sure what happends in C, but in C++, rest of the stuff aside, the following declares two types.
struct profile_datagram_t
{
struct profile_t;
};
One type is named profile_datagram_t and the other is called profile_datagram_t::profile_t. The inner type declaration is just a forward declaration, so you'll need to define the type after.
struct profile_datagram_t::profile_t
{
// ...
};
Then, you can use the struct as follows:
int main ( int, char ** )
{
profile_datagram_t::profile_t profile;
}
Some compilers support a nonstandard extension to the C language (that I actually rather like, despite it being nonstandard) called anonymous structs (or unions). Code demonstration:
struct x {
int i;
};
struct y {
struct x;
};
int main(void)
{
struct y;
y.i = 1; // this accesses member i of the struct x nested in struct y
return 0;
}
In a nutshell, if you don't give the struct (or union) member a name, you can access its members directly from the containing struct (or union). This is useful in situations where you might have given it the name _, and had to do y._.i - the anonymous struct syntax is much simpler. However, it does mean that you have to remember the names of all members of both structs and ensure they never clash.
This is all, of course, a nonstandard extension, and should be used with caution. I believe it works on MSVC and can be enabled in GCC with a switch. Don't know about any other compilers. If you're worried about portability, give the member a proper name.
EDIT: According to the GCC reference (below) this behavior is being added to the upcoming C1X standard, so it won't be nonstandard for long. I doubt MSVC will support C1X since they refuse to support C99 as it is, but at least this feature is becoming part of the standard.
However, the behavior shown above is MSVC only. The C1X (and GCC without the -fms-extensions switch) syntax doesn't allow the unnamed struct member to have a name:
struct y {
struct {
int i;
};
};
int main(void) {
struct y;
y.i = 1; // this accesses member i of the struct x nested in struct y
return 0;
}
References for various compilers (they have different names but are the same concept):
GCC (unnamed fields): http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html'
MSVC (anonymous structs): http://msdn.microsoft.com/en-us/library/z2cx9y4f.aspx
Basically you can use the following format:
variable = profile_t.element
profile_t.element = ?
EDIT: In your declaration of profile_datagram_t, the proper definition for struct profile_t should be:
struct profile_t someProfile;
Let's say you have:
header profileDiagram1;
struct profile_t profile1;
profileDiagram1.someProfile = profile1;
To access length, type or *data from profile_t:
profileDiagram1.someProfile.type;
profileDiagram1.someProfile.length;
...

Resources