c struct syntax with assignment? - c

I'm trying to get my head around structs. It seems ok in theory (e.g. a very concise and clear explanation: http://www.stanford.edu/class/cs110/hws/structs.html)
But then I find this in a code I'm messing with:
static struct pci_driver ik220_driver = {
name: DRV_NAME,
id_table: ik220_tbl,
probe: ik220_init_one,
remove: ik220_remove_one,
};
What does the = operator do here?

The = initializes a struct of type pci_driver, named ik220_driver, with the specified values for fields.
You are just assigning a variable, but it's a compound type.

Work it up in parts. struct pci_driver is a type. ik220_driver is a variable name. static sets the variable scope, so the rest: = {...} is specifying the value of the variable (which in this case happens to be a struct).

Related

Initialize pointer to a struct with a compound literal

I'm new to C and I'm trying to understand the syntax for compound literals. My question is similar to Initializing a pointer to compound literals in C but I don't think that answers it. If have a struct and a type defined as a pointer to the struct like this:
typedef struct thing *thing_t;
struct thing
{
int id;
char *name;
};
Then I can create a thing_t like this:
thing_t instance = & (struct thing) {
.id = 1,
.name = "A"
};
I was wondering if there is a way to initialize a thing_t without explicitly referring to struct thing, e.g. I tried this to see if it was valid syntax:
thing_t instance = (* thing_t) {
.id = 1,
.name = "A"
};
but the compiler errors. The compiler must "know" that the thing_t type holds a pointer to a thing, but is there syntax that allows to use the two interchangably in this context?
(I don't have a particular use case for this, I'm just trying to understand how the type and the struct are related).
I was wondering if there is a way to initialize a thing_t without
explicitly referring to struct thing, e.g. I tried this to see if it
was valid syntax:
thing_t instance = (* thing_t) {
.id = 1,
.name = "A"
};
but the compiler errors. The compiler must "know" that the thing_t
type holds a pointer to a thing,
Yes, it does, though it is poor form to define a type alias that hides pointer nature, as you have done, and it is especially poor form to do so with a name that does not somehow provide a clue about that.
but is there syntax that allows to
use the two interchangably in this context?
The syntax for a compound literal includes the parenthesized type specifier. That's not a cast, it's part of the literal itself. You cannot do without it. If you want to avoid saying struct, though, then you can kill two birds with one stone by changing your type alias so that it describes the struct type itself, not a pointer to one:
typedef struct thing thing_t;
struct thing {
int id;
char *name;
};
thing_t *instance = & (thing_t) {
.id = 1,
.name = "A"
};
Not only does it work, but it's a heck of a lot clearer than your proposal. For example, the use of the & operator matches up with the clear declaration of variable instance as a pointer.

How do I initialize a const struct with a union in C

I've been trying to solve this problem for hours now. Although I found some similar questions, it just won't work.
I have a union within a struct. Now I want to initialize a const variable of this struct.
struct length
{
int minutes;
int seconds;
};
typedef struct article
{
char name[MAXLENGTH_A]
double price;
char type;
union size
{
int pages;
struct length blength;
} bsize
} art;
Now I want to initialize a const variable of this struct. I read somewhere that the following should work, but it doesn't. I always get the errors:
C2224: The operand to the left of '.pages' is not a class, structure, or union and
C2078: To many Initializers
const art book = {"Title", 24.99, NORMAL, { .pages = 50}};
I know that this example could be solved easier. But my real problem is, to initialize the 2nd element of the union, like this:
const art book = {"Title", 24.99, AUDIO, { .blength.seconds = 40}};
Neither the first, nor the second initialization is working.
Can someone tell me how do it right? I'm using C99 btw.
The { .pages = 50} construct is a designated initializer, a C99 feature unsupported by the MS C compiler (which is a C89 compiler, I'm told). This also restricts your ability to initialize unions only via their first member.
I can see these ways around this limitation: use { 50 } to initialize pages. Then forget the const and explicitly initialize .blength.seconds. The effects of const declaring objects are, uhm, overrated :-)
You need to initialise minutes and seconds
You don't need to explicitly specify member names
{"title",24.99,NORMAL,50,40}
Should sort your problem
Key is the members pages and length.minutes occupy the same memory space as its inside a union
Hope it helps

The use of a pointer to an unnamed struct in C?

What's the use for something like
typedef struct
{
int field_1;
float field_2;
}*T;
in C ?
Since a struct is a datatype in C, where the information about the datatype pointed by T is stored and how to correctly initialize a variable var that is declared as T var ?
T is an alias for a pointer to the structure. The structure itself is not a type, but T is.
T is not stored anywhere but in the compilers internal tables for types.
You can use it like
T myVariable = malloc(sizeof(*myVariable));
I would expect something like that (pointer-to-unnamed-struct) to be used in order to describe the data which are coming from outside of the program in question (e.g. given as a return value from a library function, when it is allocated and deallocated by that library). Then such typedef is just a specification how to access these data.
The use is as if the struct was named. I.e. you can access struct fields via this pointer. For example:
void fun(T p) {
if (p->field_1 == 0) p->field_2 = 1.2345;
}
If you never need to reference a structure itself by a name, there is no need to give it one. The info about structure (and its members) is stored in compiler tables in the same way as for named structures.
This construct is useful in defining complex data structures (possibly with unions) and not to pollute global name space with useless names. For example:
struct myUsefulStructure {
int stype;
union {
struct { // a structure which is never referenced itself
...
} x;
struct { // another structure which is never referenced itself
...
} y;
} u;
};

redeclared as different kind of symbol error in C

I get the error 'J_TypeInstructions' redeclared as different kind of symbol' in the following C code:
struct _J_TypeInstructions {
const char *instructionName;
} J_TypeInstructions[] = { { "j", "000010" } };
//typedef struct _J_TypeInstructions J_TypeInstructions;
Try with that instead:
struct _J_TypeInstructions {
const char *instructionName;
} J_TypeInstructions[] = { {"j"}, {"000010"} };
/* ^ ^ */
and do not use a tag name like _J_TypeInstructions as identifiers beginning with _[A-Z]* are reserved in C.
EDIT: I missed the commented line was a part of the question:
typedef struct _J_TypeInstructions J_TypeInstructions;
You already declared a variable with the identifier J_TypeInstructions. You cannot declare a type with the same name of a variable in the same scope as identifiers for variables and type names live in the same name space. Change the name of your variable to fix the issue.
J_TypeInstructions can't be both variable name and type.
First, you created a variable(an array of _J_TypeInstructions structures) called J_TypeInstructions
then you try to define type with the same name as previously defined array.
Also, as ouah mentioned in his answer, fix your braces because the way you use them now is try to initialize one char * with 2 values and that's definetelly giving you a warning.

Why can't we initialize members inside a structure?

Why can't we initialize members inside a structure ?
example:
struct s {
int i = 10;
};
If you want to initialize non-static members in struct declaration:
In C++ (not C), structs are almost synonymous to classes and can have members initialized in the constructor.
struct s {
int i;
s(): i(10)
{
}
};
If you want to initialize an instance:
In C or C++:
struct s {
int i;
};
...
struct s s_instance = { 10 };
C99 also has a feature called designated initializers:
struct s {
int i;
};
...
struct s s_instance = {
.i = 10,
};
There is also a GNU C extension which is very similar to C99 designated initializers, but it's better to use something more portable:
struct s s_instance = {
i: 10,
};
The direct answer is because the structure definition declares a type and not a variable that can be initialized. Your example is:
struct s { int i=10; };
This does not declare any variable - it defines a type. To declare a variable, you would add a name between the } and the ;, and then you would initialize it afterwards:
struct s { int i; } t = { 10 };
As Checkers noted, in C99, you can also use designated initializers (which is a wonderful improvement -- one day, C will catch up with the other features that Fortran 66 had for data initialization, primarily repeating initializers a specifiable number of times). With this simple structure, there is no benefit. If you have a structure with, say, 20 members and only needed to initialize one of them (say because you have a flag that indicates that the rest of the structure is, or is not, initialized), it is more useful:
struct s { int i; } t = { .i = 10 };
This notation can also be used to initialize unions, to choose which element of the union is initialized.
Note that in C++ 11, the following declaration is now allowed:
struct s {
int i = 10;
};
This is an old question, but it ranks high in Google and might as well be clarified.
Edit2: This answer was written in 2008 and relates to C++98. The rules for member initialization have changed in subsequent versions of the language.
Edit: The question was originally tagged c++ but the poster said it's regarding c so I re-tagged the question, I'm leaving the answer though...
In C++ a struct is just a class which defaults for public rather than private for members and inheritance.
C++ only allows static const integral members to be initialized inline, other members must be initialized in the constructor, or if the struct is a POD in an initialization list (when declaring the variable).
struct bad {
static int answer = 42; // Error! not const
const char* question = "what is life?"; // Error! not const or integral
};
struct good {
static const int answer = 42; // OK
const char* question;
good()
: question("what is life?") // initialization list
{ }
};
struct pod { // plain old data
int answer;
const char* question;
};
pod p = { 42, "what is life?" };
We can't initialize because when we declared any structure than actually what we do, just inform compiler about their presence i.e no memory allocated for that and if we initialize member with no memory for that. Normally what happens when we initialize any variable that depends on the place where we declared variable compiler allocate memory for that variable.
int a = 10;
if it's auto than in stack memory going to allocate
if it's global than in data sections memory going to allocate
So what memory is required to hold that data but in case of structure no memory is there so not possible to initialize it.
As you said it's just a member not a variable. When you declare a variable the compiler will also provide memory space for those variables where you can put values. In the case a of a struct member the compiler is not giving memory space for it, so you cannot assign values to struct members unless you create a variable of that struct type.

Resources