[5.21 LTS x86, Linux, XP] Apparent compiler bug re: SizeOf

Just starting out? Need help? Post your questions and find answers here.
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

[5.21 LTS x86, Linux, XP] Apparent compiler bug re: SizeOf

Post by BorisTheOld »

I'm posting here first to get some opinions about the use of SizeOf with fixed length string variables.

Normally, "SizeOf" gives the defined length of the fixed string, and "Len" gives the length based on any null characters that might be embedded in the string.

The following example shows how this works:

Code: Select all

Structure udtAbc
  xFixed.s{8}
EndStructure

Procedure subProcName(*uAbc.udtAbc)
  *uAbc\xFixed = LSet("", SizeOf(*uAbc\xFixed), "x")
EndProcedure

Define uAbc.udtAbc

uAbc\xFixed = "1234"

Debug uAbc\xFixed
Debug "Len = " + Len(uAbc\xFixed)
Debug "SizeOf = " + SizeOf(uAbc\xFixed)

subProcName(uAbc)

Debug uAbc\xFixed
However, the following example fails because the compiler complains about a syntax error caused by the "SizeOf" statement:

Code: Select all

Structure udtAbc
  xFixed.s{8}
EndStructure

Structure strMain
  uAbc.udtAbc
EndStructure

Procedure subProcName(*rMain.strMain)
  *rMain\uAbc\xFixed = LSet("", Len(*rMain\uAbc\xFixed), "x")  
;  *rMain\uAbc\xFixed = LSet("", SizeOf(*rMain\uAbc\xFixed), "x")  ; <--- SizeOf creates a syntax error
EndProcedure

Define rMain.strMain

rMain\uAbc\xFixed = "1234"

Debug rMain\uAbc\xFixed
Debug "Len = " + Len(rMain\uAbc\xFixed)
;Debug "SizeOf = " + SizeOf(rMain\uAbc\xFixed)  ; <--- SizeOf creates a syntax error

subProcName(rMain)

Debug rMain\uAbc\xFixed
Debug "Len = " + Len(rMain\uAbc\xFixed)
;Debug "SizeOf = " + SizeOf(rMain\uAbc\xFixed)  ; <--- SizeOf creates a syntax error
This compiler "bug" only seems to occur with fixed fields inside nested structures. It's not a major problem and we're working around it by using additional parameters to specify the lengths. However, it's adding unneeded complications to our code.

Any opinions on whether this is a compiler bug or just a perverse "feature"?

By the way, the following example works. But it uses SizeOf with the structure definition, rather than with the variable definition that works in the first example and which fails in the second example. However, it's not very useful and not as easy to use as passing length parameters.

Code: Select all

Structure udtAbc
  xFixed.s{8}
EndStructure

Structure strMain
  uAbc.udtAbc
EndStructure

Procedure subProcName(*rMain.strMain)
  *rMain\uAbc\xFixed = LSet("", SizeOf(udtAbc\xFixed), "x")  
EndProcedure

Define rMain.strMain

rMain\uAbc\xFixed = "1234"

Debug rMain\uAbc\xFixed
Debug "Len = " + Len(rMain\uAbc\xFixed)
Debug "SizeOf = " + SizeOf(udtAbc\xFixed) 

subProcName(rMain)

Debug rMain\uAbc\xFixed
Debug "Len = " + Len(rMain\uAbc\xFixed)
Debug "SizeOf = " + SizeOf(udtAbc\xFixed)
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by Demivec »

I think the SizeOf() parameter can only take a variable or structure, or the field of a variable or structure but can not go any further.

Code: Select all

SizeOf(a)     ;valid
SizeOf(a\b)   ;valid
SizeOf(a\b\c) ;invalid

@Edit: message contents were changed from when it was initially posted.
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by BorisTheOld »

Demivec wrote:I think the SizeOf() parameter needs to be either a variable or a structure but not both. In other words, you can't reference a field of a variable, only a field of a structure. You can only reference a structured variable as a whole.
Then why are the following both acceptable uses of SizeOf in the first example? They are both references to a fixed string within a structure instance.

Code: Select all

*uAbc\xFixed = LSet("", SizeOf(*uAbc\xFixed), "x")
Debug "SizeOf = " + SizeOf(uAbc\xFixed)
The following are also references to a fixed string within a structure instance, but they create a syntax error. That's what's so "perverse". :)

Code: Select all

*rMain\uAbc\xFixed = LSet("", SizeOf(*rMain\uAbc\xFixed), "x")
Debug "SizeOf = " + SizeOf(rMain\uAbc\xFixed)
This is not so much of a problem with procedures, but it is a problem with macros. We work a lot with I/O buffers and fixed length strings. And because PB doesn't use OLE strings, we've had to create a number of macros to work around PB's inability to handle embedded nulls in strings. So we make heavy use of Peek, Poke, FillMemory, and CopyMemory.

The following is a simple example that demonstrates the inconsistent usage of SizeOf. It uses the same structures as the above examples:

Code: Select all

;
;===============================================
;
;  Macro 122 : return a variable pointer (long form)
;
Macro Address (bvsDataParmName)
  @bvsDataParmName
EndMacro

;
;===============================================
;
;  Macro 168 : fill a memory block with a byte value
;
Macro FillBlock (bvsDataParmName, bvsValue)
  FillMemory(Address(bvsDataParmName), SizeOf(bvsDataParmName), bvsValue)
EndMacro

Structure udtAbc
  xFixed.s{8}
EndStructure

Structure strMain
  uAbc.udtAbc
EndStructure

Define xFixed.s{8}
Define uAbc.udtAbc
Define rMain.strMain

FillBlock(xFixed, 0)

FillBlock(uAbc\xFixed, 0)

FillBlock(rMain\uAbc\xFixed, 0)  ; <-- this statement creates a syntax error

For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by Demivec »

BorisTheOld wrote:Then why are the following both acceptable uses of SizeOf in the first example? They are both references to a fixed string within a structure instance.
I edited my former posting before you replied.

The simple answer is that you don't seem to be able to reference structured variables (or structures themselves), more than one level deep (the field level).
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by idle »

sizeof your udtAbc should be 8 or 16 in unicode
Len will return how many characters are set I don't see any bug
Windows 11, Manjaro, Raspberry Pi OS
Image
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by BorisTheOld »

Demivec wrote:I think the SizeOf() parameter can only take a variable or structure, or the field of a variable or structure but can not go any further.

Code: Select all

SizeOf(a)     ;valid
SizeOf(a\b)   ;valid
SizeOf(a\b\c) ;invalid
@Edit: message contents were changed from when it was initially posted.
To me it's a bug, although it may just be a limitation in the way Fred has structured the compiler.

Unfortunately, there's no other simple way to determine the defined length of fixed string that's embedded deep within nested structures -- which we have many of.

It can be done, but requires calculating the field length, based on its offset in the structure and the offset of the following field -- or the end point of the structure if it's the last field. However, this has to be done on a case by case basis, and can't be easily applied to macros or subroutine calls. It also makes the code very messy and difficult to maintain.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by BorisTheOld »

idle wrote:sizeof your udtAbc should be 8 or 16 in unicode
Len will return how many characters are set I don't see any bug
The problem is not with knowing the length of the structure, but with knowing the length of a fixed string field. This is more apparent when the structure contains many fields of different types, and when the fixed strings need to be referenced in specific ways.

SizeOf is needed, because Len will only return the defined length if no null characters are in the field.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by luis »

BorisTheOld wrote:Any opinions on whether this is a compiler bug or just a perverse "feature"?
As usual not having a formal definition of the language, but just the help file we all know, PB is victim of the "programming by example" paradigm.

So we can call this a bug, but Fred can just say it works as intended and the "bug" is promoted (demoted ?) to a "limitation of the language". If it's not a limitation of the language then must be a bug in the compiler.
Last edited by luis on Wed Jan 15, 2014 10:56 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
A little PureBasic review
Harry0
User
User
Posts: 13
Joined: Sun Mar 02, 2008 4:28 pm
Location: Palatine

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by Harry0 »

Does this work for you?

Code: Select all

Structure udtAbc
  xFixed.s{8}
EndStructure

Structure strMain
  uAbc.udtAbc
EndStructure

Procedure subProcName(*rMain.strMain)
  Protected *T1
  *rMain\uAbc\xFixed = LSet("", Len(*rMain\uAbc\xFixed), "x")  
  *T1 = @*rMain\uAbc\xFixed
  
  *rMain\uAbc\xFixed = LSet("", SizeOf(*T1), "x")  ; <--- SizeOf creates a syntax error(????)
EndProcedure

Define rMain.strMain
;*T2

rMain\uAbc\xFixed = "1234"

Debug rMain\uAbc\xFixed
Debug "Len = " + Len(rMain\uAbc\xFixed)
*T2 = @rMain\uAbc\xFixed
Debug "SizeOf = " + SizeOf(*T2)  ; <--- SizeOf creates a syntax error(????)

subProcName(rMain)

Debug rMain\uAbc\xFixed
Debug "Len = " + Len(rMain\uAbc\xFixed)
*T3 = @rMain\uAbc\xFixed
Debug "SizeOf = " + SizeOf(*T3)  ; <--- SizeOf creates a syntax error(????)

If you use a pointer that is attached directly to the sub field, I think this is what you are looking for, Yes or No?

Harry0
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: [5.21 LTS x86, Linux, XP] Apparent compiler bug re: Size

Post by BorisTheOld »

Harry0 wrote:Does this work for you?..........If you use a pointer that is attached directly to the sub field, I think this is what you are looking for, Yes or No?
Unfortunately, PB does not provide typed pointers, so your example just sets a length of "4", which is the length of the pointer variable itself.
luis wrote:So we can call this a bug, but Fred can just say it works as intended and the "bug" is promoted (demoted ?) to a "limitation of the language". If it's not a limitation of the language then must be a bug in the compiler.
It's certainly a limitation of the language, since there's no direct way of getting the size of the fixed string, even though there is a way of getting the length using similar syntax. But I suspect it's not a bug, as such. More likely an oversight.

I also suspect that it would be a low priority item, since I seem to be the first person to notice this in 10 years. So I'll forego posting a bug, or requesting a new feature, and hope that Fred will soon give me back the CanvasGadget focus event that disappeared from the 5.21 LTS Windows release. :wink:
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Post Reply