[SOLVED]mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in)

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

[SOLVED]mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in)

Post by jickster » Tue Feb 13, 2018 10:50 pm

The very last line of this function: why is o cast to

Code: Select all

mp_obj_type_t*
? In the debugger, the following two expressions give the same value

Code: Select all

(mp_obj_type_t*)o->type
o->type
I understand sometimes code is there so as to emphasis the intent but ... I don't see what is gained here.

Code: Select all

mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in) {
    if (MP_OBJ_IS_SMALL_INT(o_in)) {
        return (mp_obj_type_t*)&mp_type_int;
    } else if (MP_OBJ_IS_QSTR(o_in)) {
        return (mp_obj_type_t*)&mp_type_str;
    #if MICROPY_PY_BUILTINS_FLOAT
    } else if (mp_obj_is_float(o_in)) {
        return (mp_obj_type_t*)&mp_type_float;
    #endif
    } else {
        const mp_obj_base_t *o = MP_OBJ_TO_PTR(o_in);
        return (mp_obj_type_t*)o->type;
    }
}

Code: Select all

// This mp_obj_type_t struct is a concrete MicroPython object which holds info
// about a type.  See below for actual definition of the struct.
typedef struct _mp_obj_type_t mp_obj_type_t;

// Anything that wants to be a concrete MicroPython object must have mp_obj_base_t
// as its first member (small ints, qstr objs and inline floats are not concrete).
struct _mp_obj_base_t {
    const mp_obj_type_t *type MICROPY_OBJ_BASE_ALIGNMENT;
};
typedef struct _mp_obj_base_t mp_obj_base_t;
Last edited by jickster on Wed Feb 14, 2018 4:28 pm, edited 1 time in total.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in)

Post by dhylands » Wed Feb 14, 2018 3:47 am

The cast is being applied like this:
(mp_obj_type_t *)o->type is equivalent to (mp_obj_type_t *)(o->type)
o->type is of type const mp_obj_type_t *
So the cast is removing the const

If you try removing the cast then you get a compiler error:

Code: Select all

CC ../../py/obj.c
../../py/obj.c:51:16: error: returning 'const mp_obj_type_t *const' (aka 'const struct _mp_obj_type_t *const') from a function with result type 'mp_obj_type_t *' (aka 'struct _mp_obj_type_t *')
      discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
        return o->type;
               ^~~~~~~
1 error generated.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in)

Post by jickster » Wed Feb 14, 2018 4:27 pm

dhylands wrote:
Wed Feb 14, 2018 3:47 am
The cast is being applied like this:
(mp_obj_type_t *)o->type is equivalent to (mp_obj_type_t *)(o->type)
o->type is of type const mp_obj_type_t *
So the cast is removing the const

If you try removing the cast then you get a compiler error:

Code: Select all

CC ../../py/obj.c
../../py/obj.c:51:16: error: returning 'const mp_obj_type_t *const' (aka 'const struct _mp_obj_type_t *const') from a function with result type 'mp_obj_type_t *' (aka 'struct _mp_obj_type_t *')
      discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
        return o->type;
               ^~~~~~~
1 error generated.
Oops. Order of operation. I thought the cast was happening first.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: [SOLVED]mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in)

Post by dhylands » Wed Feb 14, 2018 5:01 pm

I believe that precedence is the correct terminology. The "member access through a pointer" (->) has higher precedence than a cast, so its applied first.
See: http://en.cppreference.com/w/c/language ... precedence

Post Reply