Skip to content

Commit a968888

Browse files
stinosdpgeorge
authored andcommitted
py/obj: Fix mp_obj_is_type compilation with C++.
Fixes issue micropython#12951. Signed-off-by: stijn <stijn@ignitron.net>
1 parent 92741a3 commit a968888

3 files changed

Lines changed: 19 additions & 7 deletions

File tree

examples/usercmodule/cppexample/example.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
extern "C" {
22
#include <examplemodule.h>
3+
#include <py/objstr.h>
34

45
// Here we implement the function using C++ code, but since it's
56
// declaration has to be compatible with C everything goes in extern "C" scope.
67
mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj) {
8+
// The following no-ops are just here to verify the static assertions used in
9+
// the public API all compile with C++.
10+
MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE;
11+
if (mp_obj_is_type(a_obj, &mp_type_BaseException)) {
12+
}
13+
714
// Prove we have (at least) C++11 features.
815
const auto a = mp_obj_get_int(a_obj);
916
const auto b = mp_obj_get_int(b_obj);

py/misc.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,15 @@ typedef unsigned int uint;
5252

5353
// Static assertion macro
5454
#define MP_STATIC_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)]))
55-
#if defined(_MSC_VER)
56-
#define MP_STATIC_ASSERT_NOT_MSC(cond) (1)
55+
// In C++ things like comparing extern const pointers are not constant-expressions so cannot be used
56+
// in MP_STATIC_ASSERT. Note that not all possible compiler versions will reject this. Some gcc versions
57+
// do, others only with -Werror=vla, msvc always does.
58+
// The (void) is needed to avoid "left operand of comma operator has no effect [-Werror=unused-value]"
59+
// when using this macro on the left-hand side of a comma.
60+
#if defined(_MSC_VER) || defined(__cplusplus)
61+
#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)1)
5762
#else
58-
#define MP_STATIC_ASSERT_NOT_MSC(cond) MP_STATIC_ASSERT(cond)
63+
#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) MP_STATIC_ASSERT(cond)
5964
#endif
6065

6166
// Round-up integer division

py/obj.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -928,10 +928,10 @@ void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type);
928928
// optimizations (other tricks like using ({ expr; exper; }) or (exp, expr, expr) in mp_obj_is_type() result
929929
// in missed optimizations)
930930
#define mp_type_assert_not_bool_int_str_nonetype(t) ( \
931-
MP_STATIC_ASSERT_NOT_MSC((t) != &mp_type_bool), assert((t) != &mp_type_bool), \
932-
MP_STATIC_ASSERT_NOT_MSC((t) != &mp_type_int), assert((t) != &mp_type_int), \
933-
MP_STATIC_ASSERT_NOT_MSC((t) != &mp_type_str), assert((t) != &mp_type_str), \
934-
MP_STATIC_ASSERT_NOT_MSC((t) != &mp_type_NoneType), assert((t) != &mp_type_NoneType), \
931+
MP_STATIC_ASSERT_NONCONSTEXPR((t) != &mp_type_bool), assert((t) != &mp_type_bool), \
932+
MP_STATIC_ASSERT_NONCONSTEXPR((t) != &mp_type_int), assert((t) != &mp_type_int), \
933+
MP_STATIC_ASSERT_NONCONSTEXPR((t) != &mp_type_str), assert((t) != &mp_type_str), \
934+
MP_STATIC_ASSERT_NONCONSTEXPR((t) != &mp_type_NoneType), assert((t) != &mp_type_NoneType), \
935935
1)
936936

937937
#define mp_obj_is_type(o, t) (mp_type_assert_not_bool_int_str_nonetype(t) && mp_obj_is_exact_type(o, t))

0 commit comments

Comments
 (0)