← index #9890Issue #388
Related · high · value 2.314
QUERY · ISSUE

mp_obj_t type is not a C++ constant expression

openby nomisopened 2022-11-08updated 2023-02-17
bug

Despite only containing constant values, the following causes a C++ compiler to allocate the struct in RAM and generate a static initialiser function:

const struct {
    mp_obj_t y = MP_ROM_INT(42);
} x;

Forcing the compiler to treat it as a constant expression explains what the problem is:

constexpr const struct {
    mp_obj_t y = MP_ROM_INT(42);
} x;
in constexpr expansion of ‘<unnamed struct>()’
error: value ‘85’ of type ‘mp_obj_t {aka void*}’ is not a constant expression

C++ forbids the use of pointers in constant expressions unless they refer to a static object, a function or are nullptr. There's no way around this.

Object representations A, B and C use a void* type for mp_obj_t. This makes it impossible to initialise an mp_obj_t value at compile time for them in C++ code. Changing mp_obj_t to uintptr_t makes this work but then mp_const_obj_t is no longer const in any representation. Perhaps the type could be changed to uintptr_t only if __cplusplus is defined?

CANDIDATE · ISSUE

mp_const_none and friends are lvalue variables

closedby pfalconopened 2014-03-29updated 2014-03-29

As I suspected, mp_const_none and friends are not constant expressions, but variables with const modifier. Besides being non-efficient, it's also make impossible to do stuff like:

static mp_obj_t arr[] = {mp_const_none};

Instead of current impl, we should define them as:

#define mp_const_none (mp_obj_t)&mp_const_none_obj

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied