ATTRIBUTE(3)

πŸ“¦ version 11.0, in nixpkgs unstable

πŸ’… ATTRIBUTE(3) β€” non-standard compiler attribute extensions ✨

okay so this is ATTRIBUTE(3) from the Library Functions Manual, and it's basically the group chat where all your fave __-prefixed macros live. buckle up bestie, there's a lot of them and they're all iconic in their own way πŸŽ€


✨ SYNOPSIS ✨

#include <sys/cdefs.h>

__dead

__pure

__constfunc

__noinline

__unused

__used

__diagused

__debugused

__packed

__aligned(x);

__section(section);

__read_mostly

__cacheline_aligned

__predict_true(exp);

__predict_false(exp);

__printflike(fmtarg, firstvararg);

__sysloglike(fmtarg, firstvararg);

πŸ¦‹ DESCRIPTION πŸ¦‹

so like, as an extension to the C standard, some compilers are like "yes queen" and allow non-standard attributes to be attached to functions, variables, or types, so you can tweak some aspect of how the compiler treats that item. ngl it's giving main character energy but for your code πŸ’…

The GNU Compiler Collection (GCC), and LLVM/Clang, use the __attribute__ syntax for these attributes β€” but plot twist 😭 different versions of the compilers support different attributes, and other compilers may use entirely different syntax. messy, right?

NetBSD code should usually avoid direct use of __attribute__ or similar compiler-specific syntax. instead, NetBSD's <sys/cdefs.h> header file hands you several attribute macros in a namespace reserved for the implementation (they all start with β€˜__’, iykyk), and those macros expand to the appropriate syntax for whatever compiler is actually in use. slay 🫢


πŸ‘‘ ATTRIBUTES πŸ‘‘

  • __dead β€” Some functions, like abort(3) and exit(3), literally can never return. when one of those is declared with __dead, certain optimizations become possible and warnings that are sensitive to the code flow graph may get pruned. and obviously (emphasis on obviously) a __dead function can never have a return type other than void. periodt.
  • __pure β€” a __pure function is defined as one that has no effects except the return value, which is assumed to depend only on the function parameters and/or global variables. any access to parameters and/or global variables must also be read-only. a function that depends on volatile memory, or any other comparable system resource that can change between two consecutive calls, can never be __pure. a bunch of math(3) functions satisfy the definition of a __pure function β€” at least in theory πŸ’€. other examples include strlen(3) and strcmp(3).
  • __constfunc β€” a "const function" is a stricter variant of "pure functions". on top of everything pure functions already restrict, a function declared with __constfunc can never access global variables and can't take pointers as parameters. its return value must depend only on the passed-by-value parameters. also note: a function that calls non-const functions can't be __constfunc. the canonical example of a const function is abs(3). and just like with pure functions, certain micro-optimizations are possible for functions declared with __constfunc. two for one πŸ“
  • __noinline β€” sometimes you just know inlining is undesirable, or that a function will perform incorrectly when inlined. the __noinline macro expands to a function attribute that stops the compiler from inlining the function, no matter whether the function was declared with the inline keyword or not. this attribute takes precedence over all other compiler options related to inlining. it said "not today" πŸ’…
  • __unused β€” marking an unused function with __unused inhibits warnings that a function is defined but not used. marking a variable with __unused inhibits warnings that the variable is unused, or that it's set but never read. it's the "leave her alone" macro fr fr.
  • __used β€” the __used macro expands to an attribute that tells the compiler a static variable or function is to be always retained in the object file even if nothing references it. it stays. no cap.
  • __diagused β€” the __diagused macro expands to an attribute that tells the compiler a variable or function is used only in diagnostic code, and may be unused in non-diagnostic code.
    • In the kernel: variables that are used when DIAGNOSTIC is defined, but unused when DIAGNOSTIC is not defined, may be declared with __diagused.
    • In userland: variables that are used when NDEBUG is not defined, but unused when NDEBUG is defined, may be declared with __diagused.
    • Variables used only in assert(3) or KASSERT(9) macros are likely candidates for being declared with __diagused. πŸ‘€
  • __debugused β€” the __debugused macro expands to an attribute that tells the compiler a variable or function is used only in debug code, and may be unused in non-debug code.
    • In either the kernel or userland: variables that are used when DEBUG is defined, but unused when DEBUG is not defined, may be declared with __debugused.
    • In the kernel: variables used only in KDASSERT(9) macros are likely candidates for being declared with __debugused. There is no established convention for the use of DEBUG in userland code. πŸ™ˆ
  • __packed β€” the __packed macro expands to an attribute that forces a variable or structure field to have the smallest possible alignment, potentially disregarding architecture-specific alignment requirements. smallest possible alignment is effectively one byte for variables and one bit for fields. if specified on a struct or union, all variables therein are also packed. __packed is often useful when dealing with data that's in a particular static format on the disk, wire, or memory. lowkey the ✨compact✨ queen.
  • __aligned(x) β€” the __aligned() macro expands to an attribute that specifies the minimum alignment in bytes for a variable, structure field, or function. in other words, the specified object should have an alignment of at least x bytes, as opposed to the minimum alignment requirements dictated by the architecture and the ABI. possible use cases include:
    • Mixing assembly and C code.
    • Dealing with hardware that may impose alignment requirements greater than the architecture itself.
    • Using instructions that may impose special alignment requirements. a typical example would be alignment of frequently used objects along processor cache lines.
⚠️ note that when used with functions, structures, or structure members, __aligned() can only be used to increase the alignment. if the macro is however used as part of a typedef, the alignment can both increase and decrease. otherwise it's only possible to decrease the alignment for variables and fields by using the __packed macro. the effectiveness of __aligned() is largely dependent on the linker. the __alignof__(3) operator can be used to examine the alignment. bestie, read that twice 😭
  • __section(section) β€” the __section() macro expands to an attribute that specifies a particular section to which a variable or function should be placed. normally the compiler places the generated objects into sections such as β€œdata” or β€œtext”. by using __section(), it's possible to override this behavior β€” maybe so you can place some variables into particular sections specific to unique hardware. custom real estate 🏠
  • __read_mostly β€” the __read_mostly macro uses __section() to place a variable or function into the β€œ.data.read_mostly” section of the (kernel) elf(5). using __read_mostly lets infrequently modified data be grouped together; it's expected that the cachelines of rarely and frequently modified data structures get separated this way. candidates for __read_mostly include variables that are initialized once, read very often, and seldom written to. read-only icon behavior πŸ’–
  • __cacheline_aligned β€” the __cacheline_aligned macro behaves like __read_mostly, but the section used is β€œ.data.cacheline_aligned” instead. it also uses __aligned() to set the minimum alignment into a predefined coherency unit. this should ensure frequently used data structures are aligned on cacheline boundaries. both __cacheline_aligned and __read_mostly are only available for the kernel.
  • __predict_true β€” okay so a branch is generally defined as a conditional execution of a program depending on whether a certain flow control mechanism is altered. typical example would be an β€œif-then-else” sequence used in high-level languages, or a jump instruction used in machine-level code. a branch prediction would then be defined as an attempt to guess whether a conditional branch will be taken. The macros __predict_true() and __predict_false() annotate the likelihood of whether a branch will evaluate to true or false. the rationale? improving instruction pipelining. semantically, __predict_true expects that the integral expression exp yields nonzero. πŸ”₯
  • __predict_false β€” the __predict_false expands to an attribute that instructs the compiler to predict that a given branch will be likely false. and because programmers are notoriously bad at predicting the likely behavior of their own code 😭, profiling and empirical evidence should precede the use of __predict_false and __predict_true. do not just vibe-guess this one.
  • __printflike(fmtarg, firstvararg) β€” marks a function as taking printf-like arguments. fmtarg is the index of the format string in the argument list, and firstvararg is the index of the first item of the vararg list.
  • __sysloglike(fmtarg, firstvararg) β€” marks a function as taking syslog-like arguments. allows use of the %m formatting code. fmtarg is the index of the format string in the argument list, and firstvararg is the index of the first item of the vararg list, or 0 if the argument is a va_list. don't forget the zero case bestie 🧚

🌈 SEE ALSO 🌈

clang(1), gcc(1), __builtin_object_size(3), cdefs(3), c(7)


πŸ’€ CAVEATS πŸ’€

it goes without saying (but we're saying it anyway) that portable applications should steer clear from non-standard extensions specific to any given compiler. and even when portability is not a concern β€” use these macros sparsely and wisely. no overdoing it, queen. moderation is the vibe check.


🌸 that's the whole page, bestie β€” written by the Debian crew and dated September 14, 2018. go forth and annotate responsibly ✨🫢

πŸ“¦ where this page comes from