Tonight bug catch

General FreeBASIC programming questions.
fxm
Moderator
Posts: 12157
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Post by fxm »

Because that is more generic for any fixed string.
For example with Wstring:
dim As Wstring Ptr pw = New Byte[(length+1) * Sizeof(Wstring)]
Dim As Wstring Ptr pw = Callocate(length+1, Sizeof(Wstring))
(with Sizeof(Wstring) = 2 in that case)


[edit]
Better syntax without warning.
Last edited by fxm on Nov 14, 2016 15:19, edited 3 times in total.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Tonight bug catch

Post by MrSwiss »

fxm wrote:Because that is more generic for any fixed string.
Well, to me adding a (mul 1) is simply a waste of resources ...
I agree with you on: SizeOf(), but NOT on Len()

(you've used Len(), if you'll want to check again)
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Tonight bug catch

Post by Josep Roca »

It returns pointer expected.

Besides cws.wstr, I can use **cws because I have overloaded the * operator as follows:

Code: Select all

' ========================================================================================
' One * returns the address of the CWSTR buffer.
' Two ** deferences the string data.
' Needed because LEFT and RIGHT (cws) fail with an ambiguous call error.
' We have to use **cws (notice the double indirection) with these functions.
' ========================================================================================
PRIVATE OPERATOR * (BYREF cws AS CWSTR) AS WSTRING PTR
   OPERATOR = cast(WSTRING PTR, cws.m_pBuffer)
END OPERATOR
' ========================================================================================
So I can use:

Code: Select all

DIM cws AS CWSTR
cws = "1234567890"
MID(**cws, 3, 1) = "x"
print cws
What I don't understand is why if the CAST operator and the wstr function return the same value, cws.wstr works and the cast operator don't.
fxm
Moderator
Posts: 12157
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Post by fxm »

For @dkl,
For @Josep Roca,

Indeed, implicit byref casting works for a Zstring but not for a Wstring (not working for modifying the referred variable), although the matched operator Cast is well called in the two cases.
Nevertheless, an explicit casting ('Cast(datatype, instance)', with matched operator Cast defined in the UDT) is allowed for String, but not for Zstring neither for Wstring (see bug report #752).

- For Zstring, implicit byref casting works:

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 = Callocate(length+1 * Sizeof(Zstring))
End Constructor
Destructor UDTzstring ()
  Deallocate(This.pz)
End Destructor
Operator UDTzstring.Cast () Byref As Zstring
  Print "called: UDTzstring.Cast() Byref As Zstring"
  Return *This.pz
End Operator

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

Print *u.pz
'Mid(Cast(Zstring, u), 5, 6) = "Basic"  '' Cast(Zstring, u) not alloced
Mid(u, 5, 6) = "Basic"
Print *u.pz

Sleep

Code: Select all

Free      1.06.0
called: UDTzstring.Cast() Byref As Zstring
FreeBasic 1.06.0
- For Wstring, implicit byref casting does not work for modifying the referred variable:

Code: Select all

Type UDTwstring
  Declare Constructor (Byval length As Integer)
  Declare Destructor ()
  Declare Operator Cast () Byref As Wstring
  Dim As Wstring Ptr pw
End Type
Constructor UDTwstring (Byval length As Integer)
  This.pw = Callocate(length+1, Sizeof(Wstring))
End Constructor
Destructor UDTwstring ()
  Deallocate(This.pw)
End Destructor
Operator UDTwstring.Cast () Byref As Wstring
  Print "called: UDTwstring.Cast() Byref As Wstring"
  Return *This.pw
End Operator

Dim As UDTWstring u = UDTwstring(16)
*u.pw = "Free      1.06.0"

Print *u.pw
'Mid(Cast(Wstring, u), 5, 6) = "Basic"  '' Cast(Wstring, u) not allowed
Mid(u, 5, 6) = "Basic"
Print *u.pw

Sleep

Code: Select all

Free      1.06.0
called: UDTwstring.Cast() Byref As Wstring
Free      1.06.0
By cons, that works with a member function returning by reference the wstring ('*This.pw').

@dkl,
How the compiler succeeds the implicit byref casting with Zstring and not with Wstring (not working for modifying the referred variable) while the matched operator Cast is well called in the two cases.
fxm
Moderator
Posts: 12157
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Post by fxm »

Up to fbc 1.00.0, any type of Casting to Zstring and to Wstring was forbidden (both for explicit casting and implicit casting).

About that, I remember the following post of dkl (http://www.freebasic.net/forum/viewtopi ... 73#p196673):
dkl wrote:Looks like allowing cast(zstring, ...) was a bug introduced during the 64bit port. I've fixed it for now, though ultimately we may end up allowing zstring to be used as data type on its own (not just with Byref) anyways, for example in order to fix #650. And it makes sense to allow it when dealing with Byref things anyways.
.....
This works since 00d8aa37 (found via git bisect), and while it surely wasn't directly intended, it's an indirect side-effect and makes sense to me. There will be an implicit dereference done for the Byref As Zstring function result, and thanks to the overload resolution fixes related to that, the Byref As Zstring function result can now be used with Print or string assignments.
So, that works presently as said dkl ('Byref As Zstring function result can now be used with Print or string assignments'), but in the particular case of implicit casting by modifying the referred variable, that works only for Zstring and not for Wstring.
jdmcbride
Posts: 28
Joined: Aug 06, 2016 16:13

Re: Tonight bug catch

Post by jdmcbride »

I found a misspelling in net.bi.

this:

Function NetReciveString(

needs to be changed to:

Function NetReceiveString(

And at the end of the function, this:

NetReciveString=l

needs to be changed to:

NetReceiveString=l


I cant believe I found this, after all this time.... Anyway, my freebasic server monitoring routines are now happily mailing me updates.... and to top it off, the examples I've found for sending SMTP are now working properly too.

Jerry
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Tonight bug catch

Post by MrSwiss »

Got another one (or the Point has been missed: in FB-DOC)
FB-DOC wrote: In procedure definitions, Private specifies that a procedure has internal linkage, meaning its name is not visible to external modules.
(gives a syntax error in: -lang "fb") MUST BE WRITTEN HERE! (I thought, it was a workaround for -lang "fb")
The Option Private statement allows procedures to be defined with internal linkage by default. (Page: Option Private: states clearly, NOT allowed in -lang "fb")

Code: Select all

Declare Private Sub      DoNothing()           '' (1) error 17: Syntax error, found 'Private' in 'Declare Private Sub      DoNothing()'
Declare Private Function Ret_One() As UInteger '' (2) error 17: Syntax error, found 'Private' in 'Declare Private Function Ret_One() As UInteger'

' ----- Start Prog. ----- '
Sleep 5000, 1 ' <--- just wait 5 Sec. before 'quitting'
' ----- END Prog. ----- '

' implementation(s)
Private Sub DoNothing()
	' a lot of nothing
End Sub

Private Function Ret_One() As UInteger
	Return 1
End Function
' ----- EOF ----- '
Is PRIVATE 'implicit' in -lang "fb" ?? By the same token: do I have to declare PUBLIC ??

Is the 'syntax error' the problem ?? BTW: tested with both current Compilers: 32-ASM (WIN), 64-GCC (WIN)
fxm
Moderator
Posts: 12157
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Post by fxm »

Per default, all procedures are public.
'Private / Public' must be only put in the header of the procedure definition, not in the declaration
(similar rule as for 'Export', 'Constructor', static, but for these at end of procedure header).
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Tonight bug catch

Post by MrSwiss »

fxm wrote:Per default, all procedures are public.
Yes, this I've read, somewhere in DOC. That's the reason, I've been puzzled ...
fxm wrote:'Private / Public' must only be put in: the procedure implementation (NEVER: in the declaration)
This should be added to DOC on page: Private (IMO). Also, that it works on -lang "fb" (as opposed to: Option Private).
Maybe a additional example, showing the correct way to go ... (examples are below standard, at the moment).
Thx. fxm, for the explanation.
fxm
Moderator
Posts: 12157
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Tonight bug catch

Post by fxm »

fxm wrote:- For Wstring, implicit byref casting does not work for modifying the referred variable:

Code: Select all

Type UDTwstring
  Declare Constructor (Byval length As Integer)
  Declare Destructor ()
  Declare Operator Cast () Byref As Wstring
  Dim As Wstring Ptr pw
End Type
Constructor UDTwstring (Byval length As Integer)
  This.pw = Callocate(length+1, Sizeof(Wstring))
End Constructor
Destructor UDTwstring ()
  Deallocate(This.pw)
End Destructor
Operator UDTwstring.Cast () Byref As Wstring
  Print "called: UDTwstring.Cast() Byref As Wstring"
  Return *This.pw
End Operator

Dim As UDTWstring u = UDTwstring(16)
*u.pw = "Free      1.06.0"

Print *u.pw
'Mid(Cast(Wstring, u), 5, 6) = "Basic"  '' Cast(Wstring, u) not allowed
Mid(u, 5, 6) = "Basic"
Print *u.pw

Sleep

Code: Select all

Free      1.06.0
called: UDTwstring.Cast() Byref As Wstring
Free      1.06.0
Whether calling the Cast operator by static binding (code above) or by dynamic binding (code below with virtual Cast operator), the result is always bad as if the compiler always provided a wstring copy from the Cast operator return:

Code: Select all

Type UDTwstring Extends Object
  Declare Constructor (Byval length As Integer)
  Declare Destructor ()
  Declare Virtual Operator Cast () Byref As Wstring
  Dim As Wstring Ptr pw
End Type
Constructor UDTwstring (Byval length As Integer)
  This.pw = Callocate(length+1, Sizeof(Wstring))
End Constructor
Destructor UDTwstring ()
  Deallocate(This.pw)
End Destructor
Virtual Operator UDTwstring.Cast () Byref As Wstring
  Print "called: UDTwstring.Cast() Byref As Wstring"
  Return *This.pw
End Operator

Dim As UDTWstring u = UDTwstring(16)
*u.pw = "Free      1.06.0"

Print *u.pw
'Mid(Cast(Wstring, u), 5, 6) = "Basic"  '' Cast(Wstring, u) not allowed
Mid(u, 5, 6) = "Basic"
Print *u.pw

Sleep
But if one bypasses the compiler by calling directly in the vtable the function pointer corresponding to the Cast operator, that works:

Code: Select all

Type UDTwstring Extends Object
  Declare Constructor (Byval length As Integer)
  Declare Destructor ()
  Declare Virtual Operator Cast () Byref As Wstring
  Dim As Wstring Ptr pw
End Type
Constructor UDTwstring (Byval length As Integer)
  This.pw = Callocate(length+1, Sizeof(Wstring))
End Constructor
Destructor UDTwstring ()
  Deallocate(This.pw)
End Destructor
Operator UDTwstring.Cast () Byref As Wstring
  Print "called: UDTwstring.Cast() Byref As Wstring"
  Return *This.pw
End Operator

Dim As UDTWstring u = UDTwstring(16)
*u.pw = "Free      1.06.0"

Print *u.pw
'Mid(Cast(Wstring, u), 5, 6) = "Basic"  '' Cast(Wstring, u) not allowed
Dim As Function(Byref As UDTwstring) Byref As Wstring cast_operator = Cast(Any Ptr Ptr Ptr, @u)[0][0]
Mid(cast_operator(u), 5, 6) = "Basic"
Print *u.pw

Sleep

Code: Select all

Free      1.06.0
called: UDTwstring.Cast() Byref As Wstring
FreeBasic 1.06.0
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Tonight bug catch

Post by Tourist Trap »

Small issue. Open Cons without "FOR INPUT/OUTPUT" is not caught by the parser, it triggers a rather strange memory fault (crash) at runtime only.

Code: Select all

open cons as #1
    print #1, "hello"
close #1

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

Re: Tonight bug catch

Post by fxm »

In addition, it seems that:
- Without "FOR INPUT / FOR OUTPUT", runtime error 1 (illegal function call).
- With "FOR INPUT", only input mode is supported.
- With "FOR OUTPUT", input and output modes are simultaneously (in the same file) supported.

KeyPgOpenCons → fxm [Added a warning about the real behavior presently different from that described]
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Tonight bug catch

Post by Tourist Trap »

fxm wrote: KeyPgOpenCons → fxm [Added a warning about the real behavior presently different from that described]
I'm still exploring screenres flags and there is some conflict with OPEN CONS.

Code: Select all

#include "fbgfx.bi"
using fb

screenres 640, 400, 8, 1, GFX_OPENGL 'or GFX_FULLSCREEN

   open cons for output as #1
      print #1, "hello"
   close #1
   
sleep

@fxm, I think open cons is not a console in the standard meaning but rather a file command outputting to the console, that's why I find it surprising that in this defined context, the printing fails. Anyway that's why it should not conflict with opengl in theory, like other files. What do I miss?
sancho2
Posts: 547
Joined: May 17, 2015 6:41

Re: Tonight bug catch

Post by sancho2 »

It should be (shouldn't it?):

Code: Select all

print #1,, "hello"    'add comma
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Tonight bug catch

Post by Tourist Trap »

sancho2 wrote:It should be (shouldn't it?):

Code: Select all

print #1,, "hello"    'add comma
Finally it seems to work , it sends the data to the console. But the opengl windows is hanging, so I guess this is due to sleep. What is the opengl command to replace sleep then?
Or I don't know what is going bad. We can't go and add mutexes inside whatever thread is started at the opengl side (if it does), so it's just hard to conclude.
It would be cool to keep open cons working while opengl activated.
Post Reply