Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Positioning GCC attributes in declarations

Tags:

c

gcc

Does the GCC compiler care where we put the attribute statements inside of declarations? For example is the following equivalent:

void foobar (void) __attribute__ ((section ("bar")));

__attribute__ ((section ("bar"))) void foobar (void);

I have seen here that there is no convention on how they are used. Sometimes before declaration, sometimes after.

like image 300
Michael Munta Avatar asked Jul 03 '26 22:07

Michael Munta


1 Answers

Yes, GCC does care when the function has a body which is e.g. the case for static inline function.

  • <attr> <declaration>; is legal
  • <declaration> <attr>; is legal
  • <declaration> <definition> <attr> is legal
  • <declaration> <attr> <definition> is not legal

This is extremely problematic, because C23 does it differently. In C23 we have the following:

  • <attr> <declaration>; is not legal
  • <declaration> <attr>; is legal
  • <declaration> <definition> <attr> is not legal
  • <declaration> <attr> <definition> is legal

The consequence is, that there is no syntactically valid way to define a macro that expands to either the GCC __attribute__ or the C23 [[attribute]], depending on availability, when a function body exists.

The only overlapping legal syntax that works for both GCC and C23 attributes is

  • <declaration> <attr>;

A solution (a bad one in my opinion) is to always forward declare the function with attributes and define it separately. This obviously creates redundant code. Another solution would be to define two macros and enclose the declaration between those two:

<macro1> <declaration> <macro2> <body>

with the following definitions

#if _STDC_VERSION_ > 202300L
#define macro1 // nothing
#define macro2 [[unsequenced]] // just for example
#else
#define macro1 __attribute__((__unsequenced__))
#define macro2 // nothing
#endif

Example

The following example illustrates this with int square(int x).

Legal

__attribute__((__unsequenced__))
int square(int x) {
  return x*x;
}
int square(int x) {
  return x*x;
} __attribute__((__unsequenced__))
int square(int x) __attribute__((__unsequenced__));

int square(int x) {
  return x*x;
}
int square(int x) [[unsequenced]];

int square(int x) {
  return x*x;
}
int square(int x) [[unsequenced]] {
  return x*x;
}

Illegal

int square(int x) __attribute__((__unsequenced__)) {
  return x*x;
}
[[unsequenced]] int square(int x) {
  return x*x;
}
int square(int x) {
  return x*x;
} [[unsequenced]]
like image 190
UniversE Avatar answered Jul 06 '26 13:07

UniversE



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!