tags:

views:

64

answers:

2

Hi:

Is there any alternative to non-ISO gcc specific extension __attribute__ on 64-bit kernels ?

Three types that i've noticed are: function attributes, type attributes and variable attributes.

eg. i'd like to avoid using __attribute__((__packed__)) for structures passed over the network, even though some gcc based code do use it.

Any suggestions or pointers on how to entirely avoid __attribute__ usage in C systems/kernel code ?

thanks Saifi.

+1  A: 

Any suggestions or pointers on how to entirely avoid attribute usage in C systems/kernel code?

You can build your network packets piece by piece, copying each data element into the correct place in a char* buffer.

Pros: you don't have any alignment issues and it's generally portable, especially if you use the exact-width integer types from <stdint.h>

Cons: it's tedious and potentially error-prone

James McNellis
Hi James:Thanks for your reply.i'd like to avoid all the gcc - Function, Variable and Type attributes. Please seehttp://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.htmlhttp://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.htmlhttp://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Type-Attributes.htmleg.__attribute__ ((__transparent_union__));i'm sure that all these gcc extensions are not portable across the various C compilers and what is thrown in an convenience later comes to haunt as 'vendor-lockin'.My focus is ISO conforming C system/kernel code.
Saifi Khan
@Saifi: If you don't want to use implementation-specific structure packing attributes, then you need to do what I describe in my answer or some variation thereof: copy each struct member into the correct place in a character buffer.
James McNellis
@Safi: the "vendor lock-in" isn't a big problem if you're careful. All serious compilers will provide some means of getting the layout you want, it's just not standard. So the worst case usually is that you have to re-define all your structs for the new compiler. A big stack of `asserts` in your test suite based on `sizeof` and `offsetof` will ensure that you catch any problems before they bite. Call it "easily-portable" code, as opposed to true portable code.
Steve Jessop
@Steve Jessop: Thank you for your reply. i prefer 'simplicity' to 'convenience' !
Saifi Khan
A: 

I'm assuming based on your comments that its your code you want to change, not the whole Linux kernel (etc).

Not sure about function attributes etc but specifically for attribute packed, I have done the following with no issues so far.

Basically instead of relying on the compiler to pack, you could use manual pad fields coupled with compile-time asserts.

struct foo {
   u32 field1;
   u16 field2;
   u16 pad; // manual padding
   // continue for other fields that the compiler would automatically pad for you with attribute packed
   u32 field3;
};

To check your structure you can use a compile time assert, something like this:

#define CASSERT(cond, name) typedef cassert__##name[cond ? 1 : -1]

CASSERT(offsetof(foo, field1) == 0, field1_wrong);
CASSERT(offsetof(foo, field2) == 4, field2_wrong);

When your assertions are wrong, the build will fail with a helpful error and line number

Sam Post