bmx-ng / bcc

A next-generation bcc parser for BlitzMax
zlib License
33 stars 13 forks source link

Assigning a varptr to a struct variable leads to broken C code #581

Closed GWRon closed 2 years ago

GWRon commented 2 years ago

As discussed in the #code channel of the discord server I made this example here to "reference" a struct:

SuperStrict
Framework Brl.StandardIO

Struct Animal
  Field name:String
  Field legCount:Int = 4
End Struct

Local dog:Animal
dog.name = "dog"
dog.legCount = 4

'this would NOT modify the original dog as structs copy...
Local bird:Animal = dog
bird.name = "bird"
bird.legCount = 2

Print "dog: " + dog.name + " has " + dog.legCount +" legs."
Print "bird: " + bird.name + " has " + bird.legCount +" legs."

'modifying dog now via pointer
Print "trying pointer referenced struct changes"
Local dogPtr:Animal Ptr = Varptr dog
dogPtr.name = "spider"
dogPtr.legCount = 8
Print "dog: " + dog.name + " has " + dog.legCount +" legs."

if you replaced the line:

Local dogPtr:Animal Ptr = Varptr dog

with

Local dogPtr:Animal = Varptr dog

it does not throw an error by bcc.

yet it generates some C code which does not compile:

/.bmx/untitled2.bmx.console.release.linux.x64.c: In function ‘_bb_main’:
/.bmx/untitled2.bmx.console.release.linux.x64.c:137:41: error: invalid initializer
   struct _m_untitled2_Animal bbt_dogPtr=(&bbt_dog);
                                         ^

The C code:

int _bb_main(){
    if (!_bb_main_inited) {
        _bb_main_inited = 1;
        __bb_brl_blitz_blitz();
        __bb_brl_standardio_standardio();
        bbObjectRegisterStruct((BBDebugScope *)&_m_untitled2_Animal_scope);
        struct _m_untitled2_Animal bbt_dog=_m_untitled2_Animal_New_ObjectNew();
        bbt_dog.__m_untitled2_animal_name =((BBString*)&_s0);
        bbt_dog.__m_untitled2_animal_legcount =4;
        struct _m_untitled2_Animal bbt_bird=bbt_dog;
        bbt_bird.__m_untitled2_animal_name =((BBString*)&_s1);
        bbt_bird.__m_untitled2_animal_legcount =2;
        brl_standardio_Print(bbStringConcat(bbStringConcat(bbStringConcat(bbStringConcat(((BBString*)&_s2),bbt_dog.__m_untitled2_animal_name ),((BBString*)&_s3)),bbStringFromInt(bbt_dog.__m_untitled2_animal_legcount )),((BBString*)&_s4)));
        brl_standardio_Print(bbStringConcat(bbStringConcat(bbStringConcat(bbStringConcat(((BBString*)&_s5),bbt_bird.__m_untitled2_animal_name ),((BBString*)&_s3)),bbStringFromInt(bbt_bird.__m_untitled2_animal_legcount )),((BBString*)&_s4)));
        brl_standardio_Print((BBString*)&_s6);
        struct _m_untitled2_Animal bbt_dogPtr=(&bbt_dog);   // <--------- HIGHLIGHTED LINE
        bbt_dogPtr.__m_untitled2_animal_name =((BBString*)&_s7);
        bbt_dogPtr.__m_untitled2_animal_legcount =8;
        brl_standardio_Print(bbStringConcat(bbStringConcat(bbStringConcat(bbStringConcat(((BBString*)&_s2),bbt_dog.__m_untitled2_animal_name ),((BBString*)&_s3)),bbStringFromInt(bbt_dog.__m_untitled2_animal_legcount )),((BBString*)&_s4)));
        return 0;
    }
    return 0;
}

Is there a way for BCC detect this "wrong usage" and throw an informative error? Or is there a way to make this line "work" (so having two animal structs pointing to the same memory) -- something like Local spider:Animal = UnknownCommand(varptr dog)

HurryStarfish commented 2 years ago

Is there a way for BCC detect this "wrong usage" and throw an informative error?

Yes, Local dogPtr:Animal = Varptr dog should definitely a type error. Casting a pointer to a user-defined struct doesn't really make sense.