4 ms·
I work with a codebase that implements a sort of OO inheritance in C. It looks like this: #define BASE_FIELDS int a; int b; int c; struct Base {
by ufo 8y ago
I work with a codebase that implements a sort of OO inheritance in C. It looks like this:
#define BASE_FIELDS int a; int b; int c;
struct Base {
BASE_FIELDS
};
struct Derived1 {
BASE_FIELDS
int d; int e;
};
struct Derived2 {
BASE_FIELDS
int f; int g;
};
Then, it has lots of code that accesses Derived objects through a `Base*`, with ->a and so on.
Is this against the standard C aliasing rules? If so, how would this need to be rewritten to conform to the standard?
- comex 8y agoIt is against the rules. To fix that, you'd need to put a field of type 'struct Base' in the derived struct(s) rather than just copying its fields. edit: If you want to keep the existing syntax and can use GCC extensions, it should be legal to use an unnamed union: struct Derived1 { union { struct Base base; struct { int a; int b; int c; }; }; int d; int e; }; edit2: or, with -fms-extensions, just struct Derived1 { struct Base; int d; int e; };
- ufo 8y agoPutting a field of type 'struct Base' adds extra padding in my case, unfortunately.
- loa-in-backup 8y agoI believe there is a way to disable field alignment on a case-by-case basis. I could be wrong, though.
- comex 8y agoYes, there's the GCC extension __attribute__((packed)), or #pragma pack, an extension supported by both GCC-style compilers and MSVC.
- Taniwha 8y agooriginally fields (or rather structure offsets) in C were GLOBAL and could be used with any struct pointer, the Unix V6/V7 kernels used this to good effect, because of this unions weren't really needed (you just used a different field name from a different structure)
- Veedrac 8y agoThat is well-defined. "One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the complete type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members."
- rcxdude 8y agoThis does technically require that a union of those structs exists, even though it is not used. I don't know of any compiler for which this actually makes a difference though.
- Veedrac 8y agoAh, I misunderstood the context, you are right to clarify this.
- ufo 8y agoI checked and we actually have a give union for everything. I didn't mention it because I accidentally got rid of it when simplifying my question (the original is full of macros). Looks like we are in the clear! :)