Open GWRon opened 2 years ago
SuperStrict
framework brl.standardio
Local value:Object = String(1.2345:Float)
Local q:Byte Ptr[10]
'segfault
(Int Ptr (Varptr q[0]))[0] = value.ToString().ToFloat()
'works
Local qPtr:Byte Ptr = Varptr(q[0])
(Int Ptr qptr)[0] = value.ToString().ToFloat()
becomes:
BBOBJECT bbt_value=(BBOBJECT)((BBString*)&_s0);
BBARRAY bbt_q=bbArrayNew1D("*b", 10);
//segfault
BBINT* bbt_=((BBINT*)((BBBYTE**)BBARRAYDATA(bbt_q,1))[0U]);
bbt_[0]=((BBINT)bbStringToFloat((BBSTRING)(bbt_value)->clas->ToString((BBOBJECT)bbt_value)));
//works
BBBYTE* bbt_qPtr=(&((BBBYTE**)BBARRAYDATA(bbt_q,1))[0U]);
BBINT* bbt_=((BBINT*)bbt_qPtr);
bbt_[0]=((BBINT)bbStringToFloat((BBSTRING)(bbt_value)->clas->ToString((BBOBJECT)bbt_value)));
As you see the difference is only in the way bbt_
and bbt_qPtr
are constructed (pointer stuff). Yet both pieces of code should in my opinion be of the same "logic" (within bmx language)
Using the "direct c-code" allows to play around with the generated code right from within BlitzMax:
SuperStrict
framework brl.standardio
Local q:Byte Ptr[10]
'works
'!BBBYTE* bbt_qPtrTEST=(&((BBBYTE**)BBARRAYDATA(bbt_q,1))[0U]);
'!BBINT* bbt_=((BBINT*)bbt_qPtrTEST);
'!bbt_[0]=1;
'segfault
'!//BBINT* bbt_=((BBINT*)((BBBYTE**)BBARRAYDATA(bbt_q,1))[0U]);
'!//bbt_[0]=1;
merging the two lines of the "works" into a single line ... exposes the difference more easily:
//works
BBINT* bbt_=((BBINT*)(&((BBBYTE**)BBARRAYDATA(bbt_q,1))[0U]));
//segfault
BBINT* bbt_=((BBINT*) ((BBBYTE**)BBARRAYDATA(bbt_q,1))[0U]) ;
So somehow it misses to add the ampersand in the single-line-blitzmax version
This compiles - while I forgot a "varptr"
But with "compiles" I mean it generates invalid C code.
Added the varptr ... and the compiled thing segfaulted.. until I rewrote it partially:
(yfyi it is extracted from reflection.mod - tried stuff because of invoke() failing with floats)