Conversion from const char* to mp_rom_error_text_t ?
The compiler can't evaluate the strcmp tree generated by MP_ERROR_TEXT(x) at compile time if x is determined at runtime (for example a call to an old style xxx_strerror function):
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT(ffs_strerror(res)));
This results in a copy of the tree for every invocation of MP_ERROR_TEXT, so the return result can't be compressed and must be cast to mp_rom_error_text_t instead. This should be safe for now, but will it change in the future ? And if so, shouldn't there be a function or macro to hide this conversion since all exceptions formally accept mp_rom_error_text_t arg ? Something like:
#define MP_ERROR_TEXT_FROM_STR(x) (mp_rom_error_text_t) x
mp_obj_t type is not a C++ constant expression
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?