My first question wasn't well formulated so here goes again, this time, more well asked and explained.
I want to hide the variables of a struct while being able to initialize the struct statically on the stack. Most solutions out there use the opaque pointer idiom and dynamic memory allocation which isn't always desired.
The idea for this example came from the following post:
https://www.reddit.com/r/C_Programming/comments/aimgei/opaque_types_and_static_allocation/
I know that this is probably ub but I believe it should work fine in most consumers archictures: either 32 bit or 64 bit.
Now you may tell me that sometimes size_t may be bigger than void * and that the void * alignment in the union forcing the union alignment to be that of sizeof(void *) may be wrong, but usually that's never case, maybe it can happen but I see it as the exception not the rule.
Based on the fact that most compilers add padding to align it to either a multiple of 4 or 8 depending on your architecture and that sizeof returns the correct size with padding, sizeof(Vector) and sizeof(RealVector) should be the same, and based on the fact that both Vector and RealVector have the same alignment it should be fine too.
If this is ub, how can I create a sort of scratchpad structure in C in a safe maner? In C++ we have alignas, alignof and placement new which hepls making this ordeal a lot more safer.
If that's not possible to do in C99, will it be more safer in C11 with alignas and alignof?
#include <stdint.h>
#include <stdio.h>
/* In .h */
typedef union Vector {
uint8_t data[sizeof(void *) + 2 * sizeof(size_t)];
/* this is here to the force the alignment of the union to that of sizeof(void *) */
void * alignment;
} Vector;
void vector_initialize_version_a(Vector *);
void vector_initialize_version_b(Vector *);
void vector_debug(Vector const *);
/* In .c */
typedef struct RealVector {
uint64_t * data;
size_t length;
size_t capacity;
} RealVector;
void
vector_initialize_version_a(Vector * const t) {
RealVector * const v = (RealVector *)t;
v->data = NULL;
v->length = 0;
v->capacity = 8;
}
void
vector_initialize_version_b(Vector * const t) {
*(RealVector *)t = (RealVector) {
.data = NULL,
.length = 0,
.capacity = 16,
};
}
void
vector_debug(Vector const * const t) {
RealVector * v = (RealVector *)t;
printf("Length: %zu\n", v->length);
printf("Capacity: %zu\n", v->capacity);
}
/* In main.c */
int
main() {
/*
Compiled with:
clang -std=c99 -O3 -Wall -Werror -Wextra -Wpedantic test.c -o main.exe
*/
printf("%zu == %zu\n", sizeof(Vector), sizeof(RealVector));
Vector vector;
vector_initialize_version_a(&vector);
vector_debug(&vector);
vector_initialize_version_b(&vector);
vector_debug(&vector);
return 0;
}
I'll post my answer from the previous question, which I didn't have to time to post :)
Am I safe doing this?
No, you are not. But instead of finding a way of doing it safe, just error when it's not safe:
#include <assert.h>
#include <stdalign.h>
static_assert(sizeof(Vector) == sizeof(RealVector), "");
static_assert(alignof(Vector) == alignof(RealVector), "");
With checks written in that way, you will know beforehand when there's going to be a problem, and you can then fix it handling the specific environment. And if the checks will not fire, you will know it's fine.
how can I create a sort of scratchpad structure in C in a safe maner?
The only correct way of really doing it safe would be a two step process:
first compile a test executable that would output the size and alignment of struct RealVector
then generate the header file with proper structure definition struct Vector { alignas(REAL_VECTOR_ALIGNMENT) unigned char data[REAL_VECTOR_SIZE]; };
and then continue to compiling the final executable
Compilation of test and final executables has to be done using the same compiler options, version and settings and environment.
Notes:
Instead of union use struct with alignof
uint8_t is an integer with 8-bits. Use char, or best unsigned char, to represent "byte".
sizeof(void*) is not guaranteed to be sizeof(uint64_t*)
where max alignment is either 4 or 8 - typically on x86_64 alignof(long double) is 16.
Why nor simple? It avoids the pointer punning
typedef struct RealVector {
uint64_t * data;
size_t length;
size_t capacity;
} RealVector;
typedef struct Vector {
uint8_t data[sizeof(RealVector)];
} Vector;
typedef union
{
Vector v;
RealVector rv;
} RealVector_union;
void vector_initialize_version_a(void * const t) {
RealVector_union * const v = t;
v -> rv.data = NULL;
v -> rv.length = 0;
v -> rv.capacity = 8;
}
And
One possibility is to define Vector as follows in the .h file:
/* In vector.h file */
struct RealVector {
uint64_t * data;
size_t length;
size_t capacity;
};
typedef union Vector {
char data[sizeof(struct RealVector)];
/* these are here to the force the alignment of the union */
uint64_t * alignment1_;
size_t alignment2_;
} Vector;
That also defines struct RealVector for use in the vector implementation .c file:
/* In vector.c file */
typedef struct RealVector RealVector;
This has the advantage that the binary contents of Vector actually consists of a RealVector and is correctly aligned. The disadvantage is that a sneaky user could easily manipulate the contents of a Vector via pointer type casting.
A not so legitimate alternative is to remove struct RealVector from the .h file and replace it with an anonymous struct type of the same shape:
/* In vector.h file */
typedef union Vector {
char data[sizeof(struct { uint64_t * a; size_t b; size_t c; })];
/* these are here to the force the alignment of the union */
uint64_t * alignment1_;
size_t alignment2_;
} Vector;
Then struct RealVector needs to be fully defined in the vector implementation .c file:
/* In vector.c file */
typedef struct RealVector {
uint64_t * data;
size_t length;
size_t capacity;
} RealVector;
This has the advantage that a sneaky user cannot easily manipulate the contents of a Vector without first defining another struct type of the same shape as the anonymous struct type. The disadvantage is that the anonymous struct type that forms the binary representation of Vector is not technically compatible with the RealVector type used in the vector implementation .c file because the tags and member names are different.
Related
I have a struct
typedef struct
{
int A ;
int B ;
…
} SomeStruct ;
I have an instance of SomeStruct that I want to persist to Flash memory which has a sector size of 512 bytes. What GCC attribute can I apply to that instance such that the allocation size is a multiple of 512 bytes?
The only options I can think of are :-
1) Pad the struct to make it exactly 512 bytes. This requires recalculation every time a field is added to the struct. No compiler warnings when I get it wrong. Also struct is larger than needed with normal initialisation, copying etc.
2) Place the variable in a separate Linker section. This provides full protection and warnings, but gets a bit tedious if multiple variables are used.
3) Make a union of the struct and a 512 byte array. Copes with adding extra fields until the struct is greater than 512 bytes, then fails without any warnings.
Referring 1:
#include <assert.h>
#define FLASH_BYTES (512)
#pragma pack(1)
struct flash
{
struct data
{
int i;
char c;
...
};
char pads[FLASH_BYTES - sizeof (struct data)];
};
#pragma pack()
int main(void)
{
assert(sizeof (struct flash) == FLASH_BYTES);
...
The assert might even not be necessary because if the result
FLASH_BYTES - sizeof (struct data)
is negative any GCC should issue an error. To make sure it will be negative cast the result of the sizeof operation to any signed integer, like for example so:
FLASH_BYTES - (int) sizeof (struct data)
So trying to compile this
#pragma pack(1)
struct flash
{
struct data
{
int i;
char c[FLASH_BYTES];
};
char pads[FLASH_BYTES - (int) (sizeof (struct data))];
};
#pragma pack()
int main(void)
{
}
You should be giving you something like:
main.c:14:12: error: size of array ‘pads’ is negative
char pads[FLASH_BYTES - (int) sizeof (struct data)];
A portable solution is to define a union of SomeStruct, with a char array whose size is calculated to meet the necessary alignment.
typedef struct
{
int A;
int B;
char c[512];
} SomeStruct;
#define STORAGE_ALIGNMENT 512
typedef union
{
SomeStruct data;
char paddedData[((sizeof(SomeStruct) + STORAGE_ALIGNMENT - 1) / STORAGE_ALIGNMENT) * STORAGE_ALIGNMENT];
} SomeStructAligned;
Online running version (Coliru) here
The sizing formula is well known and works for any integer. Since this is a power-of-2 you could also simplify it down to the form (sizeof(SomeStruct) + (STORAGE_ALIGNMENT - 1)) & ~(STORAGE_ALIGNMENT - 1)) == (sizeof(SomeStruct) + 0x1ff) & ~0x1ff). In practice you may need ~size_t(0x1ff) on the rightmost term to ensure portability to 64-bit machines; since 0x1ff is an int (32-bit), ~0x1ff results in a 64-bit 0x00000000fffffe00 value instead of the desired 0xFFFFFFFFfffffe00 mask.
Sub-Optimal Approach
An alternative approach could have been to define a wrapper struct containing your original data plus some automatically calculated padding.
typedef struct
{
int A;
int B;
} SomeStruct;
#define STORAGE_ALIGNMENT 512
typedef struct
{
SomeStruct data;
char padding[(STORAGE_ALIGNMENT) - (sizeof(SomeStruct) % STORAGE_ALIGNMENT)];
} SomeStructAligned;
Online running version (Coliru) here.
However, the above is not perfect: if sizeof(SomeStruct) is a multiple of 512, then sizeof(padding) will be 512, wasting a quantum of storage. Whereas the union never wastes space.
You can try something like this (though it is a dirty bit trick)
#define ROUND_UP_512(x) ((x) + 511 & ~511)
struct myStruct {
// put whatever
};
union myUnion{
myStruct s;
char ensureSize[ROUND_UP_512(sizeof(myStruct))];
};
in this case the size of "myUnion" is guaranteed to be a multiple of 512 that is greater than or equal to the size of "myStruct"
Here is what I have, and there is still a problem - the compiler doesn't recognize the "my_reg" structure type.
../Source/functions.c:609:16: error: 'my_reg' undeclared (first use in this function)
ModBusIDReg = (my_reg)const_ModBusIDReg;
// define structure in flash with constants
struct
{
const unsigned char Reg00[32];
const unsigned char Reg01[32];
const unsigned char Reg02[32];
const unsigned short Reg03;
const unsigned short Reg04;
} const_ModBusIDReg =
{
"My String 1" ,
"My String 2" ,
"My String 3" ,
0 ,
0
};
// define structure in RAM, tag name "my_reg"
struct my_reg
{
unsigned char Reg00[32];
unsigned char Reg01[32];
unsigned char Reg02[32];
unsigned short Reg03;
unsigned short Reg04;
} ModBusIDReg;
// This statement is located in InitSys function.
// Both of the files where the structures were
// defined are included at the top of the file
// where InitSys function resides.
// Make a copy of const_ModBusIDReg from
// flash into ModBusIDReg in RAM.
ModBusIDReg = (my_reg)const_ModBusIDReg;
Any ideas on how to do the direct assignment ?
A type cast like this should resolve the compiler error:
ModBusIDReg = (my_reg)const_ModBusIDReg;
Or you could use memcpy():
memcpy(&ModBusIDReg, &const_ModBusIDReg, sizeof(my_reg));
(Sidenote at using memcpy(): In some cases, memory alignment might be an issue. But I'm no c expert. Using compiler-specific attributes like packed in the case of GCC might help, when you define the struct, depending on the platform, compiler, variable types used.)
You can also copy the members of the struct individually in a custom copy function, and initialize the unused parts if there are any. This would be clean, and very clear/explicit, and similar to a copy constructor / assignment operator used in C++ (deep copies are handled properly).
edit:
Since I can't add a comment above after your last edit, I add the comment here:
./Source/functions.c:609:16: error: 'my_reg' undeclared (first use in
this function) ModBusIDReg = (my_reg)const_ModBusIDReg;
In C you can use typedef in your struct type declartions, in order to avoid repeating the struct keyword throughout your code (explained in detail over here or there):
typedef struct { ... } foo;
foo x;
Here an example illustrating the mentioned ideas from above:
/* gcc -Wall -o copy_test copy_test.c && ./copy_test */
#include <stdio.h>
#include <string.h>
typedef struct {
int var;
} my_struct;
int my_copy_func(my_struct *dst, const my_struct *src)
{
if (!dst || !src)
return -1;
dst->var = src->var;
return 0;
}
int main()
{
const my_struct a = { .var = 42 };
my_struct b, c, d;
c = (my_struct)a;
memcpy(&b, &a, sizeof(b));
my_copy_func(&d, &a);
printf("b.var = %d\r\n", b.var);
printf("c.var = %d\r\n", c.var);
printf("d.var = %d\r\n", d.var);
return 0;
}
I was experimenting with C11 and VLAs, trying to declare a struct variable on the stack with only an incomplete declaration. The objective is to provide a mechanism to create a variable of some struct type without showing the internals (like the PIMPL idiom) but without the need to create the variable on the heap and return a pointer to it. Also, if the struct layout changes, I don't want to recompile every file that uses the struct.
I have managed to program the following:
private.h:
#ifndef PRIVATE_H_
#define PRIVATE_H_
typedef struct A{
int value;
}A;
#endif /* PRIVATE_H_ */
public.h:
#ifndef PUBLIC_H_
#define PUBLIC_H_
typedef struct A A;
size_t A_getSizeOf(void);
void A_setValue(A * a, int value);
void A_printValue(A * a);
#endif /* PUBLIC_H_ */
implementation.c:
#include "private.h"
#include "stdio.h"
size_t A_getSizeOf(void)
{
return sizeof(A);
}
void A_setValue(A * a, int value)
{
a->value = value;
}
void A_printValue(A * a)
{
printf("%d\n", a->value);
}
main.c:
#include <stdalign.h>
#include <stddef.h>
#include "public.h"
#define createOnStack(type, variable) \
alignas(max_align_t) char variable ## _stack[type ## _getSizeOf()]; \
type * variable = (type *)&variable ## _stack
int main(int argc, char *argv[]) {
createOnStack(A, var);
A_setValue(var, 5335);
A_printValue(var);
}
I have tested this code and it seems to work. However I'm not sure if I'm overlooking something (like aliasing, alignment or something like that) that could be dangerous or unportable, or could hurt performance. Also I want to know if there are better (portable) solutions to this problem in C.
This of course violates the effective typing rules (aka strict aliasing) because the C language does not allow an object of tye char [] to be accessed through a pointer that does not have that type (or a compatible one).
You could disable strict aliasing analysis via compiler flags like -fno-strict-aliasing or attributes like
#ifdef __GNUC__
#define MAY_ALIAS __attribute__((__may_alias__))
#else
#define MAY_ALIAS
#endif
(thanks go to R.. for pointing out the latter), but even if you do not do so, in practice everything should work just fine as long as you only ever use the variable's proper name to initialize the typed pointer.
Personally, I'd simplify your declarations to something along the lines of
#define stackbuffer(NAME, SIZE) \
_Alignas (max_align_t) char NAME[SIZE]
typedef struct Foo Foo;
extern const size_t SIZEOF_FOO;
stackbuffer(buffer, SIZEOF_FOO);
Foo *foo = (void *)buffer;
The alternative would be using the non-standard alloca(), but that 'function' comes with its own set of issues.
I am considering adopting a strategy similar to the following to solve essentially the same problem. Perhaps it will be of interest despite being a year late.
I wish to prevent clients of a struct from accessing the fields directly, in order to make it easier to reason about their state and easier to write reliable design contracts. I'd also prefer to avoid allocating small structures on the heap. But I can't afford a C11 public interface - much of the joy of C is that almost any code knows how to talk to C89.
To that end, consider the adequate application code:
#include "opaque.h"
int main(void)
{
opaque on_the_stack = create_opaque(42,3.14); // constructor
print_opaque(&on_the_stack);
delete_opaque(&on_the_stack); // destructor
return 0;
}
The opaque header is fairly nasty, but not completely absurd. Providing both create and delete functions is mostly for the sake of consistency with structs where calling the destructor actually matters.
/* opaque.h */
#ifndef OPAQUE_H
#define OPAQUE_H
/* max_align_t is not reliably available in stddef, esp. in c89 */
typedef union
{
int foo;
long long _longlong;
unsigned long long _ulonglong;
double _double;
void * _voidptr;
void (*_voidfuncptr)(void);
/* I believe the above types are sufficient */
} alignment_hack;
#define sizeof_opaque 16 /* Tedious to keep up to date */
typedef struct
{
union
{
char state [sizeof_opaque];
alignment_hack hack;
} private;
} opaque;
#undef sizeof_opaque /* minimise the scope of the macro */
void print_opaque(opaque * o);
opaque create_opaque(int foo, double bar);
void delete_opaque(opaque *);
#endif
Finally an implementation, which is welcome to use C11 as it's not the interface. _Static_assert(alignof...) is particularly reassuring. Several layers of static functions are used to indicate the obvious refinement of generating the wrap/unwrap layers. Pretty much the entire mess is amenable to code gen.
#include "opaque.h"
#include <stdalign.h>
#include <stdio.h>
typedef struct
{
int foo;
double bar;
} opaque_impl;
/* Zero tolerance approach to letting the sizes drift */
_Static_assert(sizeof (opaque) == sizeof (opaque_impl), "Opaque size incorrect");
_Static_assert(alignof (opaque) == alignof (opaque_impl), "Opaque alignment incorrect");
static void print_opaque_impl(opaque_impl *o)
{
printf("Foo = %d and Bar = %g\n",o->foo,o->bar);
}
static void create_opaque_impl(opaque_impl * o, int foo, double bar)
{
o->foo = foo;
o->bar = bar;
}
static void create_opaque_hack(opaque * o, int foo, double bar)
{
opaque_impl * ptr = (opaque_impl*)o;
create_opaque_impl(ptr,foo,bar);
}
static void delete_opaque_impl(opaque_impl *o)
{
o->foo = 0;
o->bar = 0;
}
static void delete_opaque_hack(opaque * o)
{
opaque_impl * ptr = (opaque_impl*)o;
delete_opaque_impl(ptr);
}
void print_opaque(opaque * o)
{
return print_opaque_impl((opaque_impl*)o);
}
opaque create_opaque(int foo, double bar)
{
opaque tmp;
unsigned int i;
/* Useful to zero out padding */
for (i=0; i < sizeof (opaque_impl); i++)
{
tmp.private.state[i] = 0;
}
create_opaque_hack(&tmp,foo,bar);
return tmp;
}
void delete_opaque(opaque *o)
{
delete_opaque_hack(o);
}
The drawbacks I can see myself:
Changing the size define manually would be irritating
The casting should hinder optimisation (I haven't checked this yet)
This may violate strict pointer aliasing. Need to re-read the spec.
I am concerned about accidentally invoking undefined behaviour. I would also be interested in general feedback on the above, or whether it looks like a credible alternative to the inventive VLA technique in the question.
Basically, what I want is some kind of compile-time generated version that is associated with the exact definition of a struct. If the definition of the struct changes in any way (field added, moved, maybe renamed), I want that version to change, too.
Such a version constant would be useful when reading in a previously serialized struct, to make sure that it's still compatible. The alternative would be manually keeping track of a manually specified constant, which has potentially confusing effects if incrementing it is forgotten (deserializing produces garbage), and also raises the question when exactly to increment it (during development and testing, or only during some kind of release).
This could be achieved by using an external tool to generate a hash over the struct definition, but I'm wondering if it is possible with the C compiler (and/or maybe its preprocessor) itself.
This is actually some form of introspection and so I suspect that this may not be possible at all in ANSI C, but I would be happy with a solution that works with gcc and clang.
The Windows API used to (still does?) have a size member as one of the first members of a struct, so that it knew what version of the struct it was being passed (see WNDCLASSEX as an example):
struct Foo
{
size_t size;
char *bar;
char *baz;
/* Other fields */
};
And before calling you set the size using sizeof:
struct Foo f;
f.size = sizeof(struct Foo);
f.bar = strdup("hi");
f.baz = strdup("there");
somefunc(&f);
Then somefunc would know, based on the size member, which version of the struct it was dealing with. Because sizeof is evaluated at compile time instead of run-time, this allows for backwards ABI compatibility.
There is nothing that would do it automatically, but you can build something that works reasonably reliably: you can use sizeof and offsetof, and combine them in such a way that the order in which you combine them mattered. Here is an example:
#include <stdio.h>
#include <stddef.h>
#define COMBINE2(a,b) ((a)*31+(b)*11)
#define COMBINE3(a,b,c) COMBINE2(COMBINE2(a,b),c)
#define COMBINE4(a,b,c,d) COMBINE2(COMBINE3(a,b,c),d)
typedef struct A {
int a1;
char a2;
float a3;
} A;
typedef struct B {
int b1;
char b2;
double b3;
} B;
typedef struct C {
char c2;
int c1;
float c3;
} C;
typedef struct D {
int d1;
char d2;
float d3;
int forgotten[2];
} D;
int main(void) {
size_t aSign = COMBINE4(sizeof(A), offsetof(A,a1), offsetof(A,a2), offsetof(A,a3));
size_t bSign = COMBINE4(sizeof(B), offsetof(B,b1), offsetof(B,b2), offsetof(B,b3));
size_t cSign = COMBINE4(sizeof(C), offsetof(C,c1), offsetof(C,c2), offsetof(C,c3));
size_t dSign = COMBINE4(sizeof(D), offsetof(D,d1), offsetof(D,d2), offsetof(D,d3));
printf("%ld %ld %ld %ld", aSign, bSign, cSign, dSign);
return 0;
}
This code prints
358944 478108 399864 597272
As you can see, this code produces run-time constants for each structure that reacts to re-ordering of fields of different lengths and changing fields' types. It also reacts to adding fields even if you forget to update the list of fields on which you base your computation, which should produce some sort of a safety net.
C11 adds, among other things, 'Anonymous Structs and Unions'.
I poked around but could not find a clear explanation of when anonymous structs and unions would be useful. I ask because I don't completely understand what they are. I get that they are structs or unions without the name afterwards, but I have always (had to?) treat that as an error so I can only conceive a use for named structs.
Anonymous union inside structures are very useful in practice. Consider that you want to implement a discriminated sum type (or tagged union), an aggregate with a boolean and either a float or a char* (i.e. a string), depending upon the boolean flag. With C11 you should be able to code
typedef struct {
bool is_float;
union {
float f;
char* s;
};
} mychoice_t;
double as_float(mychoice_t* ch)
{
if (ch->is_float) return ch->f;
else return atof(ch->s);
}
With C99, you'll have to name the union, and code ch->u.f and ch->u.s which is less readable and more verbose.
Another way to implement some tagged union type is to use casts. The Ocaml runtime gives a lot of examples.
The SBCL implementation of Common Lisp does use some union to implement tagged union types. And GNU make also uses them.
A typical and real world use of anonymous structs and unions are to provide an alternative view to data. For example when implementing a 3D point type:
typedef struct {
union{
struct{
double x;
double y;
double z;
};
double raw[3];
};
}vec3d_t;
vec3d_t v;
v.x = 4.0;
v.raw[1] = 3.0; // Equivalent to v.y = 3.0
v.z = 2.0;
This is useful if you interface to code that expects a 3D vector as a pointer to three doubles. Instead of doing f(&v.x) which is ugly, you can do f(v.raw) which makes your intent clear.
struct bla {
struct { int a; int b; };
int c;
};
the type struct bla has a member of a C11 anonymous structure type.
struct { int a; int b; } has no tag and the object has no name: it is an anonymous structure type.
You can access the members of the anonymous structure this way:
struct bla myobject;
myobject.a = 1; // a is a member of the anonymous structure inside struct bla
myobject.b = 2; // same for b
myobject.c = 3; // c is a member of the structure struct bla
Another useful implementation is when you are dealing with rgba colors, since you might want access each color on its own or as a single int.
typedef struct {
union{
struct {uint8_t a, b, g, r;};
uint32_t val;
};
}Color;
Now you can access the individual rgba values or the entire value, with its highest byte being r. i.e:
int main(void)
{
Color x;
x.r = 0x11;
x.g = 0xAA;
x.b = 0xCC;
x.a = 0xFF;
printf("%X\n", x.val);
return 0;
}
Prints 11AACCFF
I'm not sure why C11 allows anonymous structures inside structures. But Linux uses it with a certain language extension:
/**
* struct blk_mq_ctx - State for a software queue facing the submitting CPUs
*/
struct blk_mq_ctx {
struct {
spinlock_t lock;
struct list_head rq_lists[HCTX_MAX_TYPES];
} ____cacheline_aligned_in_smp;
/* ... other fields without explicit alignment annotations ... */
} ____cacheline_aligned_in_smp;
I'm not sure if that example strictly necessary, except to make the intent clear.
EDIT: I found another similar pattern which is more clear-cut. The anonymous struct feature is used with this attribute:
#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
#define __randomize_layout __attribute__((randomize_layout))
#define __no_randomize_layout __attribute__((no_randomize_layout))
/* This anon struct can add padding, so only enable it under randstruct. */
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end } __randomize_layout;
#endif
I.e. a language extension / compiler plugin to randomize field order (ASLR-style exploit "hardening"):
struct kiocb {
struct file *ki_filp;
/* The 'ki_filp' pointer is shared in a union for aio */
randomized_struct_fields_start
loff_t ki_pos;
void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
void *private;
int ki_flags;
u16 ki_hint;
u16 ki_ioprio; /* See linux/ioprio.h */
unsigned int ki_cookie; /* for ->iopoll */
randomized_struct_fields_end
};
Well, if you declare variables from that struct only once in your code, why does it need a name?
struct {
int a;
struct {
int b;
int c;
} d;
} e,f;
And you can now write things like e.a,f.d.b,etc.
(I added the inner struct, because I think that this is one of the most usages of anonymous structs)