Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions Include/pymacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,19 +199,23 @@
} while(0)
#endif

/* Get the number of elements in a visible array

This does not work on pointers, or arrays declared as [], or function
parameters. With correct compiler support, such usage will cause a build
error (see Py_BUILD_ASSERT_EXPR).

Written by Rusty Russell, public domain, http://ccodearchive.net/

Requires at GCC 3.1+ */
#if (defined(__GNUC__) && !defined(__STRICT_ANSI__) && \
(((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ >= 4)))
/* Two gcc extensions.
&a[0] degrades to a pointer: a different type from an array */
// Get the number of elements in a visible array.
//
// This does not work on pointers, or arrays declared as [], or function
// parameters. With correct compiler support, such usage will cause a build
// error (see Py_BUILD_ASSERT_EXPR).
//
// Written by Rusty Russell, public domain, http://ccodearchive.net/
//
// Require GCC 4 (it works on GCC 3.1).
//
// Two GCC extensions: &a[0] degrades to a pointer, a different type from an
// array.
//
// gh-158810: Do not use __builtin_types_compatible_p() in strict C ANSI mode
// and on C++.
#if (defined(__GNUC__) && __GNUC__ >= 4 \
&& !defined(__STRICT_ANSI__) && !defined(__cplusplus))
#define Py_ARRAY_LENGTH(array) \
(sizeof(array) / sizeof((array)[0]) \
+ Py_BUILD_ASSERT_EXPR(!__builtin_types_compatible_p(typeof(array), \
Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_cext/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ test_macros(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
{
PyObject *obj, *dict;
PyObject *slots[1];
int small_array[] = {2, 5, 7};

// test Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR()
Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int));
Expand Down Expand Up @@ -134,6 +135,9 @@ test_macros(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
Py_END_CRITICAL_SECTION();
Py_DECREF(dict);

// Test Py_ARRAY_LENGTH()
assert(Py_ARRAY_LENGTH(small_array) == 3);

Py_RETURN_NONE;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :c:macro:`Py_ARRAY_LENGTH()` macro on C++: do not use
``__builtin_types_compatible_p()`` on C++. Patch by Victor Stinner.
Loading