Tonight bug catch

General FreeBASIC programming questions.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Tonight bug catch

Postby Tourist Trap » Nov 12, 2016 1:04

I'm not sure , but as far as I can judge there is something wrong with
LEFT + UDT_CAST_TO_STRING:

Code: Select all

 type TESTUDT
    declare operator cast() as string
        as integer  _dummyIntegerField
end type
operator TESTUDT.cast() as string
    return str(THIS._dummyIntegerField)
end operator

dim as TESTUDT  test
test._dummyIntegerField = 333833

'? left(test, 2)        'fbc complains about ambiguous call here

? left(str(test), 2)
? instr(test, "8")



'(eof)
fxm
Posts: 10206
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Postby fxm » Nov 12, 2016 7:36

The explicit syntax to call the operator 'Cast' (predefined or overloaded for UDT) is the following:
Cast(datatype, expression)

So in your example, the explicit syntax is:
Left(Cast(String, test), 2)
which works well.

But, depending on configuration, the compiler may applied an implicit conversion on 'expression', so that the explicit user call to the operator 'Cast' may become useless, but it is not a requirement

What is surprising is that the compiler implicit conversion works well for 'Instr', 'Mid', but not for 'Left' and 'Right' for example, inducing an 'ambiguous call' error when user does not specify the operator 'Cast' explicitly.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Tonight bug catch

Postby Tourist Trap » Nov 12, 2016 15:24

fxm wrote:What is surprising is that the compiler implicit conversion works well for 'Instr', 'Mid', but not for 'Left' and 'Right' for example, inducing an 'ambiguous call' error when user does not specify the operator 'Cast' explicitly.

This is indeed what I wanted to point out essentially. For functions that take necessarily strings as parameters, it is logical that they will seek for the possible cast_to_string in the case of a udt argument. This is correctly done with INSTR for instance. So for me the lack of this feature for LEFT, is more likely to be a bug.
I don't know if fixing this would kill some performance. If not fixed anyway, then at least the documentation should mention it. I would vote for a fix anyway.
fxm
Posts: 10206
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Postby fxm » Nov 12, 2016 17:11

marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: Tonight bug catch

Postby marpon » Nov 12, 2016 17:24

noticed the same behavior with implicit cast from udt to wstring on left : right functions

i had to overload them see here

http://www.freebasic.net/forum/viewtopic.php?f=17&t=24070&start=15#p226207
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Tonight bug catch

Postby Tourist Trap » Nov 13, 2016 0:09


Thanks for this report.


marpon wrote:noticed the same behavior with implicit cast from udt to wstring on left : right functions

i had to overload them see here

http://www.freebasic.net/forum/viewtopic.php?f=17&t=24070&start=15#p226207

Great job done there. I dont navigate within the strings varieties, but a lot of people seems in need of extended strings.
Josep Roca
Posts: 516
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Tonight bug catch

Postby Josep Roca » Nov 13, 2016 4:28

It also does not work with VAL and MID statement (works with MID as a function). There are also problems when using the & operator (the + operator always works) and possibly other FB intrinsic functions.
fxm
Posts: 10206
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Postby fxm » Nov 13, 2016 7:08

OK, that does not work for 'Val()'.
But for '&' and 'Mid()' (statement), post an example please.
Josep Roca
Posts: 516
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Tonight bug catch

Postby Josep Roca » Nov 13, 2016 8:51

A more complex class is needed to demonstrate it. I have noticed these problems with the dynamic unicode string class that I'm working.

See: http://www.planetsquires.com/protect/fo ... 1#msg29531

Regarding MID as a statement, something like MID(cws, 2, 1) = "x" compiles but does not change the contents of the dynamic unicode string.
fxm
Posts: 10206
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Postby fxm » Nov 13, 2016 9:09

Josep Roca wrote:Regarding MID as a statement, something like MID(cws, 2, 1) = "x" compiles but does not change the contents of the dynamic unicode string.
To modify a string from the object, the operator Cast() must return a reference to the string and not only a copy (Declare Operator Cast () Byref As String).

Example:

Code: Select all

Type UDT
  Declare Operator Cast() Byref As String
  Dim As String S
End Type
Operator UDT.cast() Byref As String
  Return This.S
End Operator

Dim As UDT u
u.S = "Free      1.06.0"

Dim As String Text
Text = "    Basic 1.06.0"
Print Text
Mid(Text, 1, 4) = u
Print Text
Print
Print u
Mid(u, 5, 6) = Mid(Text, 5)
Print u
fxm
Posts: 10206
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Postby fxm » Nov 13, 2016 9:45

Another example with a dynamic buffer:

Code: Select all

Type UDTzstring
  Declare Constructor (Byval length As Integer)
  Declare Destructor ()
  Declare Operator Cast() Byref As Zstring
  Dim As Zstring Ptr pz
End Type
Constructor UDTzstring (Byval length As Integer)
  This.pz = New Byte[(length+1) * Len(Zstring)]
End Constructor
Destructor UDTzstring ()
  Delete[] This.pz
End Destructor
Operator UDTzstring.Cast() Byref As Zstring
  Return *This.pz
End Operator

Dim As UDTzstring u = UDTzstring(16)
*u.pz = "Free      1.06.0"

Dim As String Text
Text = "    Basic 1.06.0"
Print Text
Mid(Text, 1, 4) = u
Print Text
Print
Print u
Mid(u, 5, 6) = Mid(Text, 5)
Print u
MrSwiss
Posts: 3725
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Tonight bug catch

Postby MrSwiss » Nov 13, 2016 10:29

fxm, the constructor above seems wrong:

Len(ZString) = 0
therefore, NEW will allocate a amount of 0 Byte:
= New Byte[(length+1) * Len(ZString)]

anything * NULL = 0 (always)

straight and narrow:
= New Byte[length + 1] does the trick (correctly, I might add)

Simple Len(ZString) TEST:

Code: Select all

Dim As ZString * 260 TS
Dim As ZString Ptr pTS = @TS
'
Print Len(*pTS) ' prints: 0
Print Len(TS)   ' prints: 0
'
Sleep
fxm
Posts: 10206
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Postby fxm » Nov 13, 2016 10:48

Len(Zstring) = Sizeof(Zstring) = 1
Don't confuse Len(Zstring) and Len(variable_zstring).
MrSwiss
Posts: 3725
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Tonight bug catch

Postby MrSwiss » Nov 13, 2016 10:54

I know that on numeric types the: mul SizeOf(Var) is needed, but
why the useless (even confusing) decoration on ZString?
Josep Roca
Posts: 516
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Tonight bug catch

Postby Josep Roca » Nov 13, 2016 10:55

Don't know where is the problem.

With my class, if I use a cast operator

Code: Select all

PRIVATE OPERATOR CWstr.CAST () BYREF AS WSTRING
   OPERATOR = *cast(WSTRING PTR, m_pBuffer)
END OPERATOR


This compiles but the content is not changed

Code: Select all

DIM cws AS CWSTR
cws = "1234567890"
MID(cws, 3, 1) = "x"
print cws


However, if I use a function instead of an operator

Code: Select all

PRIVATE FUNCTION CWstr.wstr () BYREF AS WSTRING
   RETURN *cast(WSTRING PTR, m_pBuffer)
END FUNCTION


it works

Code: Select all

DIM cws AS CWSTR
cws = "1234567890"
MID(cws.wstr, 3, 1) = "x"
print cws

Return to “General”

Who is online

Users browsing this forum: No registered users and 17 guests