Skip to content

Use C23/C++17 attributes #159464

Open
Open

Description

@encukou

Currently, we use a bunch of compiler-specific attributes: for example Py_UNUSED is defined for GCC using __attribute__(( unused )) (in a #ifdef __GNUC__ block).

This makes for a bit of a problem for non-mainstream compilers: either they define __GNUC__ to pretend they're GCC, which means they need to implement "all" of GCC's quirks, or they don't, and they don't get nice features & optimizations.

C++17 & C23 have a solution to this: the [[attribute]] syntax. You can use [[maybe_unused]] (standard C) or [[gnu::unused]] (compiler-specific), after checking availability with #if defined(__has_c_attribute) && __has_c_attribute(maybe_unused).
Other compilers can then only provide the specific attribute to get the benefit. (Providing __has_c_attribute(gnu::unused) only means that this one feature behaves like in GCC.)

Like many new C/C++ features, existing compilers implement it in older-standard-mode as extensions. (And this is all about compiler extensions.)

We should start slowly migrating to this, see how it interacts with various pedantic modes we need to support. (Alas, this part is tricky.)
Presumably, any future attributes will be exposed this way; we should be ready to use them without compiler-specific #if ladders.

cc @vstinner @fuhsnn

Linked PRs

Activity

  1. self-assigned this
    on Oct 15, 2026
  2. fuhsnn commented on Oct 17, 2026

    @fuhsnn
    Contributor

    On #if defined(__has_c_attribute) && __has_c_attribute(maybe_unused): the preprocessor converts unknown identifiers to zero, if a compiler don't support it, the condition becomes 0 && 0(maybe_used) and will error out instead of evaluating to false, like older gcc/clang here https://c.godbolt.org/z/9e388Kaa5.

    IMO it's more portable (and convenient) with a wrapper like:

    #if defined(__has_c_attribute)
    #define Py_has_c_attr(x) __has_c_attribute(x)
    #else
    #define Py_has_c_attr(x)
    #endif

    As for slimcc, which doesn't define __GNUC__, currently for trunk and 3.15 configured with CFLAGS=-std=c23 ./configure --disable-gil it seems the only attribute required to not fail unexpected tests is this use of __attribute__((section)):

    #if defined(__linux__) && (defined(__GNUC__) || defined(__clang__))
    #define _GENERATE_DEBUG_SECTION_LINUX(name) \
    __attribute__((section("." Py_STRINGIFY(name)))) \
    __attribute__((used))
    #else
    #define _GENERATE_DEBUG_SECTION_LINUX(name)
    #endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions