dots inside structs

D

dmjcunha

What mean the dots? Why are they on there? I know that nv20_context_create and nv20_context_destroy are functions, or should I say pointer to functions? Thank's in advance.

const struct nouveau_driver nv20_driver = {
.context_create = nv20_context_create,
.context_destroy = nv20_context_destroy,
...
 
D

dmjcunha

Em quinta-feira, 28 de fevereiro de 2013 13h42min44s UTC-4, (e-mail address removed) escreveu:
What mean the dots? Why are they on there? I know that nv20_context_create and nv20_context_destroy are functions, or should I say pointer to functions? Thank's in advance.



const struct nouveau_driver nv20_driver = {

.context_create = nv20_context_create,

.context_destroy = nv20_context_destroy,

...

Sorry,
I have in a header file:

struct nouveau_driver {
struct gl_context *(*context_create)(struct nouveau_screen *screen,
const struct gl_config *visual,
struct gl_context *share_ctx);
void (*context_destroy)(struct gl_context *ctx);
...
 
J

James Kuyper

What mean the dots? Why are they on there? I know that nv20_context_create and nv20_context_destroy are functions, or should I say pointer to functions? Thank's in advance.

const struct nouveau_driver nv20_driver = {
.context_create = nv20_context_create,
.context_destroy = nv20_context_destroy,
...

This is a feature of C99 called designators. It's essentially equivalent to:

const struct nouveau_driver nv20_driver;
nv20_driver.context_create = nv20_context_create;
nv20_driver.context_destroy = nv20_context_destroy;

There are several key differences, however. Since the designators are
part of the initializer for nv20_driver, the fact that it's declared
'const' doesn't violate a constraint, the way the assignment expressions
above would. Also, you can use designators for objects with file scope,
where the assignment expressions would not be allowed, or for block
scope objects with static storage duration, where the corresponding
assignment expressions would be executed every time the block is
entered, whereas the designators would only be evaluated once, before
the start of the program.

Another form of the same feature applies to arrays:

int array[5000] = {[1234] = 4321};

which is essentially equivalent to

int array[5000] = {0};
array[1234] = 4321;
 
K

Keith Thompson

What mean the dots? Why are they on there? I know that
nv20_context_create and nv20_context_destroy are functions, or should
I say pointer to functions? Thank's in advance.

const struct nouveau_driver nv20_driver = {
.context_create = nv20_context_create,
.context_destroy = nv20_context_destroy,
...

Designated initializers are a feature that was added to the language by
the 1999 ISO C standard. They're defined in section 6.7.9 of the
standard. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
is the latest draft.
 
B

Barry Schwarz

What mean the dots? Why are they on there? I know that nv20_context_create and nv20_context_destroy are functions, or should I say pointer to functions? Thank's in advance.

const struct nouveau_driver nv20_driver = {
.context_create = nv20_context_create,
.context_destroy = nv20_context_destroy,
...

You have a structure type called struct nouveau_driver. The structure
contains members context_create and context_destroy. As indicated in
your subsequent post, both these members have type pointer to function

The segment of code you quoted defines nv20_driver as a const
qualified object of type struct nouveau. Since the object is const,
it cannot be assigned to. The only way to populate its members is by
initialization. The expressions inside the braces specify how the
members of the structure are to be initialized.

As of C99, there are two forms for initializing structures.

One is the previously existing comma separated list of values.
This requires you to specify the initialization values in the same
order the members are defined within the structure (and include extra
commas for every member without a specified value).

The new .member_name form (which is what your code segment
uses) allows you to specify values for members without regard to order
or intervening members.
 
N

Nobody

The new .member_name form (which is what your code segment
uses) allows you to specify values for members without regard to order
or intervening members.

Which means that if new fields are added to the structure (other than at
the end), any existing initialisers continue to be valid, with the new
fields being implicitly initialised to a null pointer. Similarly,
existing fields can be removed without affecting existing initialisers
(other than those which initialise the removed field).

The effect is to weaken the coupling between declaration and
initialisation, so that modules only need to know about the fields which
they actually initialise, and not the complete layout of the structure.

This is advantageous given the size of the Linux kernel and the
distributed nature of its development process.
 
J

James Kuyper

Which means that if new fields are added to the structure (other than at

I think you mean "even" rather than "other than", since what you say is
always true for fields at the end. The difference is that using
designated initializers allows it to also be true for fields not at the end.
the end), any existing initialisers continue to be valid, with the new
fields being implicitly initialised to a null pointer.

That's true only if the new fields are pointers. More generally,
unspecified members are zero-initialized; zero-initialization of a
pointer makes it null.
Similarly,
existing fields can be removed without affecting existing initialisers
(other than those which initialise the removed field).

The effect is to weaken the coupling between declaration and
initialisation, so that modules only need to know about the fields which
they actually initialise, and not the complete layout of the structure.

You can only use designators in the definition of an object of that
type, which therefore must be a complete type. The complete layout of
the structure must, therefore, be known, though it need not all be used.
 
N

Nobody

That's true only if the new fields are pointers. More generally,
unspecified members are zero-initialized; zero-initialization of a
pointer makes it null.

Right; the example given in the OP is the method table for a Linux
device driver. These consist primarily of function pointers, where
typically some of the methods are optional.
You can only use designators in the definition of an object of that
type, which therefore must be a complete type. The complete layout of
the structure must, therefore, be known, though it need not all be used.

It needs to be "known" to the compiler. It doesn't need to be known to the
author of the module.
 
D

David Thompson

As of C99, there are two forms for initializing structures.

One is the previously existing comma separated list of values.
This requires you to specify the initialization values in the same
order the members are defined within the structure (and include extra
commas for every member without a specified value).
Yes the first, no the second. A comma with no initializer expression
is a syntax error. You can stop partway through, omitting the
remaining fields *and* their commas, and they are initialized to
'appropriate' zero (numeric zero for arithmetic and null for pointer).
The new .member_name form (which is what your code segment
uses) allows you to specify values for members without regard to order
or intervening members.

Right. And again any fields that aren't specified are zero-initalized.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top