pointer to constant string?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

pointer to constant string?

Post 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.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: pointer to constant string?

Post 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
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: pointer to constant string?

Post 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")
"Have you tried turning it off and on again ?"
A little PureBasic review
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: pointer to constant string?

Post 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")
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: pointer to constant string?

Post 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!
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: pointer to constant string?

Post 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.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: pointer to constant string?

Post 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!
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: pointer to constant string?

Post by Mistrel »

User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: pointer to constant string?

Post 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.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: pointer to constant string?

Post 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.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: pointer to constant string?

Post 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
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: pointer to constant string?

Post by Tenaja »

Yeah... functional workaround. But like I said, clumsy. Oh, well.
Harry0
User
User
Posts: 13
Joined: Sun Mar 02, 2008 4:28 pm
Location: Palatine

Re: pointer to constant string?

Post 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)
bosker
Enthusiast
Enthusiast
Posts: 105
Joined: Fri Jan 08, 2010 11:04 pm
Location: Hampshire, UK

Re: pointer to constant string?

Post 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

User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: pointer to constant string?

Post 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.
Post Reply