Page 1 of 2

pointer to constant string?

Posted: Thu Dec 02, 2010 5:10 pm
by Tenaja
How do I use a pointer to a constant string?

Code: Select all

Procedure TestingPointers (*s.s)
	Debug "Doing Pointers S :" + *s
	Debug @*s
EndProcedure


TestingPointers(@"CONSTANT")    ;this gives an error.
TestingPointers("CONSTANT")    ;this gives an error.
The workaround I've come up with is this, but it's messy:

ConString.s = "CONSTANT"
TestingPointers(@ConString)

...surely there's a cleaner way! (?) A good way to do it would be appreciated.

Re: pointer to constant string?

Posted: Thu Dec 02, 2010 5:21 pm
by ts-soft

Code: Select all

DataSection
  ConstantString: Data.s "My Constantstring"
EndDataSection

Define.s String = PeekS(?ConstantString)
Define *pString = ?ConstantString

Debug String
Debug *pString

Re: pointer to constant string?

Posted: Thu Dec 02, 2010 6:06 pm
by luis
Following your code, maybe you wanted this ?

Code: Select all

Procedure TestingPointers (*ptr)
 Debug *ptr
 Debug PeekC(*ptr) ; ASCII 67, THE "C"
 Debug PeekS(*ptr)
EndProcedure


TestingPointers(@"CONSTANT")

Re: pointer to constant string?

Posted: Thu Dec 02, 2010 7:25 pm
by Trond
You need to stop trying to code C in PB. PB doesn't even have constant strings. If you are referring to literal strings as constant strings, then you're using the wrong terminology.

When you declare a variable of type .s in PB, it is already a pointer under the hood. That's why pointer to string is so clumsy in PB, because you have a pointer to an invisible pointer to string data.

The expression @"some string" gives the address of the string data (array of char). However, a "pointer to pb-string" doesn't hold the pointer to the string data, it holds a pointer to the pb string variable, which is a pointer to the string data.

So when you declare a "pointer to a string", you don't declare a pointer to an array of char, but a pointer to a pointer to an array of char.

Code: Select all

Procedure TestingPointers (*s.string) ; Pointer to string variable (= pointer to pointer to string data)
   Debug "Doing Pointers S :" + *s\s
   Debug *s
EndProcedure

*ptr_to_string_data = @"LITERAL"
*ptr_to_ptr_to_string_data = @*ptr_to_string_data
TestingPointers(*ptr_to_ptr_to_string_data)
The recommended way of passing a string is like this:

Code: Select all

Procedure TestingPointers (s.s)
   Debug "Doing S :" + s
EndProcedure

TestingPointers("LITERAL")

Re: pointer to constant string?

Posted: Thu Dec 02, 2010 8:20 pm
by Tenaja
I want to pass pointers, because there's less to move, since the strings could be large.

I need to be able to pass both constants and variable strings. I don't want to have to use two different procedures.

I have what could be a lot of data to send. Currently, my workaround is a macro...but I want to eliminate the macro so the "IF FilePointer" isn't repeated at every use in the code. This shows a typical one.

Code: Select all

 Macro WriteLine(s)
 	If FilePointer 
 		WriteStringN(0, s) 
 	EndIf
 EndMacro

;in use:
WriteLine(StringData$ + "TWO")
Clearly, when I convert that to a Proc with a pointer to *s, it chokes on the "TWO":

Code: Select all

 Procedure WriteLine(*s)
 	If FilePointer 
 		WriteStringN(0, *s) 
 	EndIf
 EndProcedure

;in use:
WriteLine(@StringData$ + "TWO")   ;chokes on "TWO", but works without it
tempstring = StringData$ + "TWO"
WriteLine(@tempstring)   ;works
So, in C, I'd sprintf the string and the constant together into tempstring, then send the pointer to the tempstring. What's the best way to do this in PB? Can it be done with pointers (for compact code) and also without the tempstring?

Thanks!

Re: pointer to constant string?

Posted: Thu Dec 02, 2010 8:49 pm
by Trond
It is my opinion after some experience with PB that you should either use strings and not care about the performance, or use pointers only (no dynamic string manipulation). For the wast majority of cases, plain strings will be fast enough. If you have many big strings (like 1 mb and so on), then you should consider the pointer way, which unfortunately (but for a very good reason) is incompatible with string expressions.

The problem is that PB does automatic string management, which is very handy. However, this can't be done right if you disturb it. For example:

Code: Select all

Procedure Test(Str.s) ; CantWork(*str.string)
EndProcedure
Test(MyStr.s + "Hello")
Here, PB will handle memory management automatically. Now if you want to pass a string expression to a procedure expecting a pointer, there will be a leak, as the procedure expecting a pointer can't know if this is a pointer to data on the string heap or data heap. To prevent such problems, this is disallowed in PB. You can't mix strings which are managed by PB with pointers managed by yourself. So you must either use pointers, or strings, but not both.

Now you might think, that's retarded, in C I can use both. But you'd be wrong then, because C doesn't even have automatically managed strings. C only has array of char. You can use arrays of char in PB, too, but they can't be mixed with automatically managed PB strings, and the support for converting "literals" to array of char is bad, so you're better off with plain C in that case.

The proper way of passing around string data by pointer in PB is to wrap it in a structure and pass a pointer to the structure:

Code: Select all

; THIS IS THE WAY
Structure MyData
  Field.s
EndStructure

Procedure ExpectMyData(*Ptr.MyData)
  Debug *Ptr\Field
EndProcedure

Global MyVariable.MyData
MyVariable\Field = "Hello world"

ExpectMyData(@MyVariable)
PS. You are not the first user to come to this forum and try to code C in PB. There is a lot of new users who get disappointed because PB is "clumsy" when they try to code programming idioms of their previous language in PB. You must be aware that every programming language has its own way to reach the end goal. This is why it's a good idea for newcomers to state their goal in terms of input, output and calculation/behaviour (in addition to presumed implementation) when asking a question. Experienced users can then show the best way to accomplish this in PB. By asking only for a particular implementation you limit yourself to mediocre solutions.

Re: pointer to constant string?

Posted: Thu Dec 02, 2010 9:20 pm
by Tenaja
You are not the first user to come to this forum and try to code C in PB. There is a lot of new users who get disappointed because PB is "clumsy" when they try to code programming idioms of their previous language in PB. You must be aware that every programming language has its own way to reach the end goal.
No surprise!

Thanks a lot!

Re: pointer to constant string?

Posted: Sun Dec 05, 2010 2:35 pm
by Mistrel

Re: pointer to constant string?

Posted: Sun Dec 05, 2010 5:05 pm
by Tenaja
Which snip were you referring to, exactly? Of the ones that would compile, none of them returned a pointer to a constant string.

Re: pointer to constant string?

Posted: Sun Dec 05, 2010 5:08 pm
by Tenaja
I know I've been afflicted by C, but it seems like there's just GOT to be a simple way to assign an array of constants. Using data and a For loop just seems clumsy. Especially if you've got more than one type of data for a structure.

Re: pointer to constant string?

Posted: Sun Dec 05, 2010 7:24 pm
by Trond
Tenaja wrote:I know I've been afflicted by C, but it seems like there's just GOT to be a simple way to assign an array of constants. Using data and a For loop just seems clumsy. Especially if you've got more than one type of data for a structure.
No, this is a shortcoming in PB.

Edit:

Code: Select all

Structure SCharArray8
  StructureUnion
    c.c[16]
    s.s{15}
  EndStructureUnion
EndStructure

Structure SArray8
  elements.SCharArray8[4]
EndStructure

*MyPtr.SArray8 = ?MyData ; <- Very simple

; Check that it worked:
For I = 0 To 3
  Debug *MyPtr\elements[I]\s
Next

DataSection
  MyData:
  Data.s "First item     "
  Data.s "Second item    "
  Data.s "Third item     "
  Data.s "Fourth item    "
EndDataSection

Re: pointer to constant string?

Posted: Mon Dec 06, 2010 1:55 am
by Tenaja
Yeah... functional workaround. But like I said, clumsy. Oh, well.

Re: pointer to constant string?

Posted: Fri Jan 07, 2011 12:13 am
by Harry0
Now I might have misunderstood what you wanted (I am not a C programmer) but is this what you are looking for?

Code: Select all

;
;- Constants
;

#Test_1 = "Hello"
#test_2 = "Goodbye"

Define String_Var_1.s
Define String_Var_2.s

Procedure Filter1String(*sss.s)
  Protected x.i, y.i
  x = 0
  Y = Len(*SSS)
  If Y > 0
    Debug *SSS
  EndIf
EndProcedure

String_Var_1 = "this is a test (1)"
String_Var_2 = #Test_1 + " "+ #test_2
Filter1String(@String_Var_1)
Filter1String(@String_Var_2)

Re: pointer to constant string?

Posted: Sat Jan 08, 2011 12:22 am
by bosker
@Tenaja - how about...

Code: Select all

!macro strtbl [st]
!{
!  forward
!    local label
!    dd label
!  forward
!    label db st,0
!}
; Use as  ! strtbl "apple","ball","cat","dog"

Structure SArray
  elements.s[4]
EndStructure

Define I.i
Define *MyPtr.SArray = ?MyData

; Check that it worked:
For I = 0 To 3
  Debug *MyPtr\elements[I]
Next

DataSection
  MyData:
  ! strtbl "first item", "second item", "third item - longer then others", "fourth item"
EndDataSection


Re: pointer to constant string?

Posted: Sat Jan 08, 2011 2:25 am
by Tenaja
That's not really what I was looking for... first, you can't init an array of constant strings without the loop. That stinks. Second, you can't call a proc with a constant string when it's expecting a string pointer. (i.e. CallMyProc(x, "constant"))


BTW, what are all the exclamation points at the beginning of your lines? I haven't seen that. Thanks.