Functions in UDT with byref params

New to FreeBASIC? Post your questions here.
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Functions in UDT with byref params

Post by Iczer »

For some reason this not working -
If I declare time-strings in UDT as:
DateTime_iso8601 As ZString * 128
DateTime_RFC7231 As ZString * 128

then Print will print blank time-strings
but if I replace zString * NNN with String its working OK:

DateTime_iso8601 As String
DateTime_RFC7231 As String

Where i'm wrong?

Code: Select all

Dim Shared As tagSourceAccess Ptr pGlobal_C
pGlobal_C = New tagSourceAccess[iCount]

For i As ULong = 1 To iCount
	pGlobal_C[i].Import(i)
	pGlobal_C[i].Setup()
	
	
	' blank with zString * 128 and correct with String
	
	Print "sDateTime_UTC_iso8601 = ";pGlobal_C[i].DateTime_iso8601
	Print "sDateTime_UTC_RFC7231 = ";pGlobal_C[i].DateTime_RFC7231
Next i
this print blank strings:

Code: Select all

' .............................................................................................................................
Type tagSourceAccess
	
	iError							As Long
	iExtended						As Long
	
	iID								As ULong
	
	Name							As ZString * 2048

	DateTime_EPOCH					As LongInt
	DateTime_iso8601				As ZString * 128
	DateTime_RFC7231				As ZString * 128
	DateTime_GDateTime				As GDateTime Ptr

	Declare Function Import(iID As ULong) As Long
	Declare Function Export() As Long
	Declare Function Compare() As Long
	
	Declare Function Setup() As Long
	
	Declare Sub DebugPrint()
	
	Declare Constructor()
	Declare Constructor(ByRef tSourceAccess As tagSourceAccess)
	Declare Operator Let (ByRef tSourceAccess As tagSourceAccess)
	Declare Destructor ()
	
End Type
' .............................................................................................................................
Function tagSourceAccess.Import(iID As ULong) As Long

	This.iID			= iID
	This.name			= asGlobal(iID).name
	This.DateTime_EPOCH = asGlobal(iID).DateTime_EPOCH
	' ----------------------------------------------------------------------------------------
	DateTimeParse_EPOCHToAll(This.DateTime_EPOCH, _
												This.DateTime_iso8601, _
												This.DateTime_RFC7231, _
												This.DateTime_GDateTime)
	' ----------------------------------------------------------------------------------------
	'
	' this print blank time-strings <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	'
	' ----------------------------------------------------------------------------------------
	Print "sDateTime_UTC_iso8601 = ";This.DateTime_iso8601
	Print "sDateTime_UTC_RFC7231 = ";This.DateTime_RFC7231
	' ----------------------------------------------------------------------------------------
	This.iError = SourceAccess_OK
	This.iExtended = SourceAccess_ExtOK
	' ----------------------------------------------------------------------------------------
	Function = SourceAccess_OK
End Function
' .............................................................................................................................
' .............................................................................................................................
Function DateTimeParse_EPOCHToAll(ByRef iDateTime_Epoch As LongInt, _
																		ByRef sDateTime_UTC_iso8601 As String, _
																		ByRef sDateTime_UTC_RFC7231 As String, _
																		ByRef GDateTime_UTC_Base As GDateTime Ptr) As Integer
	' ----------------------------------------------------------------------------------------
	sDateTime_UTC_iso8601 = Space(128)
	sDateTime_UTC_RFC7231 = Space(128)
	GDateTime_UTC_Base = 0
	' ----------------------------------------------------------------------------------------
	'Print "PubDate in = ";sDateTime_SourceRFC7231
	
	Dim GDateTime_Base As GDateTime Ptr
	Dim GDateTime_Val As GTimeVal
	Dim RetValue As Boolean
	Dim As gchar Ptr Pattern_Local_iso8601 = @"%Y-%m-%dT%H:%M:%S%:z", Pattern_Local_RFC7231 = @"%a, %d %b %Y %H:%M:%S%z"
	Dim As gchar Ptr Pattern_UTC_iso8601 = @"%Y-%m-%dT%H:%M:%S %Z", Pattern_UTC_RFC7231 = @"%a, %d %b %Y %H:%M:%S %Z"
	' ----------------------------------------------------------------------------------------
	If iDateTime_Epoch > 0 Then
		GDateTime_UTC_Base	= g_date_time_new_from_unix_utc (iDateTime_Epoch)
	Else
		GDateTime_UTC_Base	= g_date_time_new_now_utc()
	EndIf
	' ----------------------------------------------------------------------------------------
	sDateTime_UTC_iso8601 = *g_date_time_format (GDateTime_UTC_Base,Pattern_UTC_iso8601)
	sDateTime_UTC_RFC7231 = *g_date_time_format (GDateTime_UTC_Base,Pattern_UTC_RFC7231)
	' ----------------------------------------------------------------------------------------
	'
	' this print correct time-strings <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	'
	' ----------------------------------------------------------------------------------------
	Print "sDateTime_UTC_iso8601 = ";sDateTime_UTC_iso8601
	Print "sDateTime_UTC_RFC7231 = ";sDateTime_UTC_RFC7231
	' ----------------------------------------------------------------------------------------
	Return 0
End Function
this print normal strings:

Code: Select all

' .............................................................................................................................
Type tagSourceAccess
	
	iError							As Long
	iExtended						As Long
	
	iID								As ULong
	
	Name							As ZString * 2048

	DateTime_EPOCH					As LongInt
	DateTime_iso8601				As String
	DateTime_RFC7231				As String
	DateTime_GDateTime				As GDateTime Ptr

	Declare Function Import(iID As ULong) As Long
	Declare Function Export() As Long
	Declare Function Compare() As Long
	
	Declare Function Setup() As Long
	
	Declare Sub DebugPrint()
	
	Declare Constructor()
	Declare Constructor(ByRef tSourceAccess As tagSourceAccess)
	Declare Operator Let (ByRef tSourceAccess As tagSourceAccess)
	Declare Destructor ()
	
End Type
' .............................................................................................................................
Function tagSourceAccess.Import(iID As ULong) As Long
	
	This.iID			= iID
	This.name			= asGlobal(iID).name
	This.DateTime_EPOCH = asGlobal(iID).DateTime_EPOCH
	' ----------------------------------------------------------------------------------------
	DateTimeParse_EPOCHToAll(This.DateTime_EPOCH, _
												This.DateTime_iso8601, _
												This.DateTime_RFC7231, _
												This.DateTime_GDateTime)
	' ----------------------------------------------------------------------------------------
	'
	' this print correct time-strings <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	'
	' ----------------------------------------------------------------------------------------
	Print "sDateTime_UTC_iso8601 = ";This.DateTime_iso8601
	Print "sDateTime_UTC_RFC7231 = ";This.DateTime_RFC7231
	' ----------------------------------------------------------------------------------------
	This.iError = SourceAccess_OK
	This.iExtended = SourceAccess_ExtOK
	' ----------------------------------------------------------------------------------------
	Function = SourceAccess_OK
End Function
' .............................................................................................................................
' .............................................................................................................................
Function DateTimeParse_EPOCHToAll(ByRef iDateTime_Epoch As LongInt, _
																		ByRef sDateTime_UTC_iso8601 As String, _
																		ByRef sDateTime_UTC_RFC7231 As String, _
																		ByRef GDateTime_UTC_Base As GDateTime Ptr) As Integer
	' ----------------------------------------------------------------------------------------
	sDateTime_UTC_iso8601 = Space(128)
	sDateTime_UTC_RFC7231 = Space(128)
	GDateTime_UTC_Base = 0
	' ----------------------------------------------------------------------------------------
	'Print "PubDate in = ";sDateTime_SourceRFC7231
	
	Dim GDateTime_Base As GDateTime Ptr
	Dim GDateTime_Val As GTimeVal
	Dim RetValue As Boolean
	Dim As gchar Ptr Pattern_Local_iso8601 = @"%Y-%m-%dT%H:%M:%S%:z", Pattern_Local_RFC7231 = @"%a, %d %b %Y %H:%M:%S%z"
	Dim As gchar Ptr Pattern_UTC_iso8601 = @"%Y-%m-%dT%H:%M:%S %Z", Pattern_UTC_RFC7231 = @"%a, %d %b %Y %H:%M:%S %Z"
	' ----------------------------------------------------------------------------------------
	If iDateTime_Epoch > 0 Then
		GDateTime_UTC_Base	= g_date_time_new_from_unix_utc (iDateTime_Epoch)
	Else
		GDateTime_UTC_Base	= g_date_time_new_now_utc()
	EndIf
	' ----------------------------------------------------------------------------------------
	sDateTime_UTC_iso8601 = *g_date_time_format (GDateTime_UTC_Base,Pattern_UTC_iso8601)
	sDateTime_UTC_RFC7231 = *g_date_time_format (GDateTime_UTC_Base,Pattern_UTC_RFC7231)
	' ----------------------------------------------------------------------------------------
	'
	' this print correct time-strings <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	'
	' ----------------------------------------------------------------------------------------
	Print "sDateTime_UTC_iso8601 = ";sDateTime_UTC_iso8601
	Print "sDateTime_UTC_RFC7231 = ";sDateTime_UTC_RFC7231
	' ----------------------------------------------------------------------------------------
	Return 0
End Function
' .............................................................................................................................
' .............................................................................................................................
Type tagSourceAccess
	
	iError							As Long
	iExtended						As Long
	
	iID								As ULong
	
	Name							As ZString * 2048

	DateTime_EPOCH					As LongInt
	DateTime_iso8601				As ZString * 128
	DateTime_RFC7231				As ZString * 128
	DateTime_GDateTime				As GDateTime Ptr

	Declare Function Import(iID As ULong) As Long
	Declare Function Export() As Long
	Declare Function Compare() As Long
	
	Declare Function Setup() As Long
	
	Declare Sub DebugPrint()
	
	Declare Constructor()
	Declare Constructor(ByRef tSourceAccess As tagSourceAccess)
	Declare Operator Let (ByRef tSourceAccess As tagSourceAccess)
	Declare Destructor ()
	
End Type
' .............................................................................................................................
Function tagSourceAccess.Import(iID As ULong) As Long

	This.iID			= iID
	This.name			= asGlobal(iID).name
	This.DateTime_EPOCH = asGlobal(iID).DateTime_EPOCH
	' ----------------------------------------------------------------------------------------
	DateTimeParse_EPOCHToAll(This.DateTime_EPOCH, _
												This.DateTime_iso8601, _
												This.DateTime_RFC7231, _
												This.DateTime_GDateTime)
	' ----------------------------------------------------------------------------------------
	'
	' thes print blank time-strings <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	'
	' ----------------------------------------------------------------------------------------
	Print "sDateTime_UTC_iso8601 = ";This.DateTime_iso8601
	Print "sDateTime_UTC_RFC7231 = ";This.DateTime_RFC7231
	' ----------------------------------------------------------------------------------------
	This.iError = SourceAccess_OK
	This.iExtended = SourceAccess_ExtOK
	' ----------------------------------------------------------------------------------------
	Function = SourceAccess_OK
End Function
' .............................................................................................................................
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Functions in UDT with byref params

Post by MrSwiss »

This is IMHO, not a problem, however, one has to take care, to use correct accessing method(s).

See demo code:

Code: Select all

Function AddStr( _
    ByVal psz_i1 As Const ZString Ptr, _
    Byval psz_i2 As Const ZString Ptr  _
    ) ByRef As Const String
    Static As String    rs
    ' to access zstring, use zstring ptr dereferenced
    rs  = *psz_i1 + *psz_i2
    Return rs
End Function

' start testing code
Dim As ZString * 128    sz1, sz2
Dim As ZString Ptr      psz1 = @sz1, psz2 = @sz2
' to access zstring, use zstring ptr dereferenced or
' access zstring, directly
*psz1 = "Free " : sz2 = "BASIC"
Print AddStr(psz1, psz2)

Sleep
' end testing code
Instead of:
ByVal As Const ZString Ptr <--> ByRef As Const ZString (could be used, too):

Code: Select all

' just the modified Function (same effect)
Function AddStr( _
    ByRef sz1 As Const ZString, _
    ByRef sz2 As Const ZString  _
    ) ByRef As Const String
    Static As String    rs
    ' access zstring, directly
    rs  = sz1 + sz2
    Return rs
End Function
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Functions in UDT with byref params

Post by fxm »

When passing a 'DataType1' variable as argument to a procedure through a 'Byref As DataType2' parameter ('DataType1' and 'DataType2' being different types), there is two possible behaviors:
- Generally, the compiler disallows this argument passing, and returns an error message "Type mismatch".
- Some times, the compiler allows this argument passing, but in fact a local 'DataType2' variable is created and initialized with the 'DataType1' argument value, then is passed by reference to the procedure. So a modification of the parameter inside the procedure body does not impact the original argument.

Passing a 'fix-len-string' argument through a 'Byref As var-len-string' parameter corresponds to the second case above.

Passing a 'var-len-string' argument through a 'Byref As zstring' (or a 'Byval As zstring ptr') parameter is a special case, because the address of the var-len-string character data is passed as zstring address. So the result (including potential crashing) strongly depends on the original var-len-string size.

In order to obtain a safe passing by reference, the two types must be the same or fully compatibles, as for example a derived UDT argument passed to a base UDT parameter (but in this last case, a derived UDT object "IS" a base UDT object, by the inheritance process).
Last edited by fxm on Dec 15, 2017 8:50, edited 7 times in total.
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: Functions in UDT with byref params

Post by Iczer »

Thanks!
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Functions in UDT with byref params

Post by fxm »

I think the precisions in my post above are of a high level of implementation, and should not pollute the documentation which must be a compromise between precision and accessibility to beginners (maybe only at most a summary note to the end of the description paragraph?).
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Functions in UDT with byref params

Post by MrSwiss »

It's been dawning on me, over time, that the FB-Reference should, similar to law,
have another Book (so to speak), that contains all those *implementation specifics*,
in detail.
In law you have: the Law itself (Book's), then (also as Book's) precedence cases,
explanatinons of the law & the precedence cases (in detail as to: how and why), etc.

This would have the following advantages:
  • not cluttering the Reference
  • easy to find, but bundled, for those *wanting to know more*
  • all those explanations aren't lost, in the forum (a major problem, well known)!
Just my 2 Cents ...
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Functions in UDT with byref params

Post by grindstone »

Good idea. Not a separate book, but splitting each item of the reference in a "general" and a (link to a) "details" section?
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Functions in UDT with byref params

Post by fxm »

Often, most of the details useful only to experienced users are placed at the end of the "Description" paragraph (either as free paragraphs following the main description or marked as notes).
But the delimitation is unclear, and there is no effort to separate a synthetic description accessible to all, and the additional details useful only for experienced programmers.
As these details add to the synthetic description, I do not see this on a separate page but rather in a separate paragraph (for example "More Details") but on the same page.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Functions in UDT with byref params

Post by Munair »

fxm wrote:As these details add to the synthetic description, I do not see this on a separate page but rather in a separate paragraph (for example "More Details") but on the same page.
Yes, that would keep things together, which I believe is the better approach.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Functions in UDT with byref params

Post by MrSwiss »

fxm wrote:Often, most of the details useful only to experienced users are placed at the end of the "Description" paragraph (either as free paragraphs following the main description or marked as notes).
But the delimitation is unclear, and there is no effort to separate a synthetic description accessible to all, and the additional details useful only for experienced programmers.
As these details add to the synthetic description, I do not see this on a separate page but rather in a separate paragraph (for example "More Details") but on the same page.
I'm getting the feeling that: you want to defend the 'status quo' at all costs, because:
I've not referred to: yet another synthetic description but, on the contrary:
1) wrap the synthetic decription in 'Laymans Terms' (so that: even a Beginner understands it!)
2) use examples to illustrate the facts, with:
  • a) working implementation and,
    b) failing implementation(s)
This then, in a different volume (apart from the Reference! To not clutter it up!).

I hope this now clears, the 'muddied waters', sufficently.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Functions in UDT with byref params

Post by St_W »

MrSwiss wrote:I've not referred to: yet another synthetic description but, on the contrary:
1) wrap the synthetic decription in 'Laymans Terms' (so that: even a Beginner understands it!)
2) use examples to illustrate the facts, with:
  • a) working implementation and,
    b) failing implementation(s)
This then, in a different volume (apart from the Reference! To not clutter it up!).
I hope this now clears, the 'muddied waters', sufficently.
You are free to contribute to the documentation or start a new documentation for the compiler implementation details. But be aware that you cannot just put a bunch of unstructured and unrelated pieces of information from the forum together and call that documentation. It's not as simple as that - that wouldn't result in a good documentation. Carefully written as simply as possible, but with enough details as necessary. That's quite a lot of work.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Functions in UDT with byref params

Post by fxm »

MrSwiss wrote:I'm getting the feeling that: you want to defend the 'status quo' at all costs
I am sorry to only propose an improvement of the current documentation (separation between synthesis and details).
But me (unlike many others), I only propose what I can do and what I would do if the principle is accepted!
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Functions in UDT with byref params

Post by MrSwiss »

fxm wrote:... what I would do if the principle is accepted!
Well then, as a starter on "if the principle is accepted!":
what do you think (in general), about the basic idea, of adding a less technical section, to the
current reference (I've no interest, in changing much of that), as a separate page (each).
E.g. <KeyPgKill> add a <KeyPgKillExpl> (just picked because: "on top, RHS index-page")

It would probably take a long time, to slowly (on a: "as we go along" base) fill up, over time.
ALSO: anybody would be invited, to help the process along. The more people involved, the
faster the progress, would be. I'm talking about: "writing the new pages", and not about:
"just delivering comments", which is more of a distraction, from the main purpose.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Functions in UDT with byref params

Post by coderJeff »

I think the fbc documenation, for keywords especially, generally get more detailed and specific the further you read down the page. But, there are many keyword pages that have notes, gotchas, warnings, etc, embedded in the description section, typically towards the end.

Please see FBWikiFaq and decide if there isn't already a place for this information.

What if we added another section after "See also", kind of like how PHP documentation has the "user contributed notes"?. A place for additional detailed, sometimes very specific situation information.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Functions in UDT with byref params

Post by Munair »

coderJeff wrote:What if we added another section after "See also", kind of like how PHP documentation has the "user contributed notes"?. A place for additional detailed, sometimes very specific situation information.
Great idea.
Post Reply