Skip to content

Commit b2bfbce

Browse files
authored
gh-158810: Fix Py_ARRAY_LENGTH() macro on C++ (#158812)
1 parent 9133d5c commit b2bfbce

3 files changed

Lines changed: 23 additions & 13 deletions

File tree

‎Include/pymacro.h‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -199,19 +199,23 @@
199199
} while(0)
200200
#endif
201201

202-
/* Get the number of elements in a visible array
203-
204-
This does not work on pointers, or arrays declared as [], or function
205-
parameters. With correct compiler support, such usage will cause a build
206-
error (see Py_BUILD_ASSERT_EXPR).
207-
208-
Written by Rusty Russell, public domain, http://ccodearchive.net/
209-
210-
Requires at GCC 3.1+ */
211-
#if (defined(__GNUC__) && !defined(__STRICT_ANSI__) && \
212-
(((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ >= 4)))
213-
/* Two gcc extensions.
214-
&a[0] degrades to a pointer: a different type from an array */
202+
// Get the number of elements in a visible array.
203+
//
204+
// This does not work on pointers, or arrays declared as [], or function
205+
// parameters. With correct compiler support, such usage will cause a build
206+
// error (see Py_BUILD_ASSERT_EXPR).
207+
//
208+
// Written by Rusty Russell, public domain, http://ccodearchive.net/
209+
//
210+
// Require GCC 4 (it works on GCC 3.1).
211+
//
212+
// Two GCC extensions: &a[0] degrades to a pointer, a different type from an
213+
// array.
214+
//
215+
// gh-158810: Do not use __builtin_types_compatible_p() in strict C ANSI mode
216+
// and on C++.
217+
#if (defined(__GNUC__) && __GNUC__ >= 4 \
218+
&& !defined(__STRICT_ANSI__) && !defined(__cplusplus))
215219
#define Py_ARRAY_LENGTH(array) \
216220
(sizeof(array) / sizeof((array)[0]) \
217221
+ Py_BUILD_ASSERT_EXPR(!__builtin_types_compatible_p(typeof(array), \

‎Lib/test/test_cext/extension.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ test_macros(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
8383
{
8484
PyObject *obj, *dict;
8585
PyObject *slots[1];
86+
int small_array[] = {2, 5, 7};
8687

8788
// test Py_BUILD_ASSERT() and Py_BUILD_ASSERT_EXPR()
8889
Py_BUILD_ASSERT(sizeof(int) == sizeof(unsigned int));
@@ -134,6 +135,9 @@ test_macros(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
134135
Py_END_CRITICAL_SECTION();
135136
Py_DECREF(dict);
136137

138+
// Test Py_ARRAY_LENGTH()
139+
assert(Py_ARRAY_LENGTH(small_array) == 3);
140+
137141
Py_RETURN_NONE;
138142
}
139143

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :c:macro:`Py_ARRAY_LENGTH()` macro on C++: do not use
2+
``__builtin_types_compatible_p()`` on C++. Patch by Victor Stinner.

0 commit comments

Comments
 (0)