GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — [C API] Py_ARRAY_LENGTH() macro is incompatible with g++ -std=gnu++11 · Issue #158810 · python/cpython

[C API] Py_ARRAY_LENGTH() macro is incompatible with g++ -std=gnu++11 #158810

New issue
Copy link
New issue
Copy link
Closed
Closed
[C API] Py_ARRAY_LENGTH() macro is incompatible with g++ -std=gnu++11#158810
Copy link
Labels
buildThe build process and cross-buildThe build process and cross-buildinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-C-APItype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@vstinner
vstinner
opened on Oct 4, 2026
Issue body actions

Bug report

Example:

#include <Python.h>

int main()
{
    int array[] = {1, 2, 3};
    return Py_ARRAY_LENGTH(array);
}

Building this example with g++ -std=gnu++11 example.cpp or just g++ example.cpp fails with:

In file included from Include/Python.h:70,
                 from x.cpp:1:
x.cpp: In function ‘int main()’:
Include/pymacro.h:217:30: error: ‘__builtin_types_compatible_p’ was not declared in this scope
  217 |      + Py_BUILD_ASSERT_EXPR(!__builtin_types_compatible_p(typeof(array), \
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

The example builds correctly if I use -std=c++11 (g++ -std=c++11 example.cpp).

The macro is currently defined as:

#define Py_ARRAY_LENGTH(array) \
    (sizeof(array) / sizeof((array)[0]) \
     + Py_BUILD_ASSERT_EXPR(!__builtin_types_compatible_p(typeof(array), \
                                                          typeof(&(array)[0]))))
#else
#define Py_ARRAY_LENGTH(array) \
    (sizeof(array) / sizeof((array)[0]))
#endif

I'm not sure why __builtin_types_compatible_p() is available with -std=c++11, but not with -std=gnu++11.

I made my tests using g++ (GCC) 16.2.1 on Fedora 44.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

  • gh-158810: Fix Py_ARRAY_LENGTH() macro on C++ #158812
  • gh-158810: Use _Py_TYPEOF in Py_ARRAY_LENGTH() #158838
  • [3.15] gh-158810: Fix Py_ARRAY_LENGTH() macro on C++ #159315
  • [3.14] gh-158810: Fix Py_ARRAY_LENGTH() macro on C++ #159317

Activity

  1. vstinner
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    topic-C-API
    on Oct 4, 2026
  2. vstinner
    changed the title [-]C API: Py_ARRAY_LENGTH() macro is incompatible with g++ -std=gnu++11[/-] [+][C API] Py_ARRAY_LENGTH() macro is incompatible with g++ -std=gnu++11[/+] on Oct 4, 2026
  3. da-woods commented on Oct 4, 2026

    @da-woods
    da-woods
    on Oct 4, 2026
    Contributor
    More actions

    The documentation for __builtin_types_compatible_p says

    Note: This construct is only available for C.

    Which leaves a mystery about why it seems to work in -std=c++11 but which does imply you shouldn't be using it in c++

  4. vstinner
    added a commit that references this issue on Oct 4, 2026

    pythongh-158810: Fix Py_ARRAY_LENGTH() macro on C++

    9d6063a
  5. vstinner commented on Oct 4, 2026

    @vstinner
    vstinner
    on Oct 4, 2026
    MemberAuthor
    More actions

    @da-woods: It would be nice to be able to use __builtin_types_compatible_p() on C++ when it's supported. The problem is that I don't know how to check if the built-in function is available or not.

    (...) which does imply you shouldn't be using it in c++

    Well well well, a simple fix is to do exactly that: don't use __builtin_types_compatible_p() on C++. I implemented this approach in PR gh-158812.

  6. chris-eibl commented on Oct 5, 2026

    @chris-eibl
    chris-eibl
    on Oct 5, 2026
    Member
    More actions

    Other places in the code base use _Py__has_builtin, but I don't think this buys us much here, since we know __builtin_types_compatible_p isn't supported in C++. Yet, it'll reduce the detection to #if _Py__has_builtin(__builtin_types_compatible_p).

    The most natural fit in modern C++ beginning with C++17 is std::size, and AI will for sure spit out something for earlier versions, but that's all template based, and you've mentioned in #157649 (comment) that templates did not play out nicely for Py_CLEAR et al.

  7. picnixz
    added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    buildThe build process and cross-buildThe build process and cross-build
    on Oct 5, 2026
  8. vstinner
    added a commit that references this issue on Oct 5, 2026

    gh-158810: Fix Py_ARRAY_LENGTH() macro on C++ (#158812)

    b2bfbce
  9. vstinner commented on Oct 5, 2026

    @vstinner
    vstinner
    on Oct 5, 2026
    MemberAuthor
    More actions

    The example builds correctly if I use -std=c++11 (g++ -std=c++11 example.cpp).

    When using -std=c++11, the __STRICT_ANSI__ macro is defined. In this case, Py_ARRAY_LENGTH() doesn't use built-in functions (it doesn't use __builtin_types_compatible_p() or typeof()).

    Other places in the code base use _Py__has_builtin, but I don't think this buys us much here, since we know __builtin_types_compatible_p isn't supported in C++. Yet, it'll reduce the detection to #if _Py__has_builtin(__builtin_types_compatible_p).

    __has_builtin(typeof) and __has_builtin(__builtin_types_compatible_p) are false using -std=c++11 and -std=gnu++11. So it cannot be used in C++ for Py_ARRAY_LENGTH().

    The most natural fit in modern C++ beginning with C++17 is std::size, and AI will for sure spit out something for earlier versions, but that's all template based, and you've mentioned in #157649 (comment) that templates did not play out nicely for Py_CLEAR et al.

    I'm sure that it's possible to write something nice using templates, but I would prefer to keep the Python C API simple, and avoid C++ templates in general.

    #define Py_ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0])) works just fine on C++.

    It's just that it doesn't detect API misuse on C++. It would be nice to have, but it's ok to not detect API misuse in this case.

    I just merged my PR to just use #define Py_ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0])) in C++.

    Thanks for your feedback @da-woods and @chris-eibl.

    Reacted by Chris Eibl
    Reacted by Chris Eibl
  10. vstinner
    closed this as completedon Oct 5, 2026
  11. vstinner
    added a commit that references this issue on Oct 6, 2026

    gh-158810: Use _Py_TYPEOF in Py_ARRAY_LENGTH() (#158838)

    85c03d4
  12. vstinner
    added 2 commits that reference this issue on Oct 13, 2026

    [3.15] gh-158810: Fix Py_ARRAY_LENGTH() macro on C++ (#159315)

    152185f

    [3.14] gh-158810: Fix Py_ARRAY_LENGTH() macro on C++ (#159317)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    buildThe build process and cross-buildThe build process and cross-buildinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-C-APItype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.