Can't get the address of a constant string

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Can't get the address of a constant string

Post by Mistrel »

You can get the address of a literal string but the PureBasic parser won't let you get the address of a constant string. This should be possible because it will become a literal after the parser performs the constant find/replace.

Code: Select all

*This=@"Hello!"
Debug PeekS(*This)

*This=@#PB_Compiler_File
Debug PeekS(*This)
Otherwise I think this is the only to pass the pointer to a constant resolved string literal to a function by address:

Code: Select all

Procedure This(*String.s)
  Debug PeekI(@*String.s)
EndProcedure

This(?CompilerFile)
This(?CompilerFile)

DataSection
  CompilerFile:
    Data.s #PB_Compiler_File
EndDataSection
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Post by helpy »

Code: Select all

CompilerIf #PB_Compiler_Unicode
  Prototype ptPassStringPointer( string.p-unicode )
CompilerElse
  Prototype ptPassStringPointer( string.p-ascii )
CompilerEndIf

Procedure procGetStringAddress( *string )
  Debug Str(*string) + "  -  " + PeekS( *string )
  ProcedureReturn *string
EndProcedure

AddrOfString.ptPassStringPointer = @procGetStringAddress()

Debug @"Hello!"                 ; @"Hello!" has the same value
Debug AddrOfString( "Hello!" )  ; as the *string, which is handled in the proc!
Debug ""

;Debug @#PB_Compiler_File
Debug AddrOfString( #PB_Compiler_File )
Debug ""

test.s = "Hello world!"
Debug @test
Debug AddrOfString( test )
Debug ""
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

That's a neat trick. 8)
I may look like a mule, but I'm not a complete ass.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Brilliant! srod is right, this is a neat trick. I wonder what else this could be useful for. Hhmm.. the possibilities. :D
User avatar
einander
Enthusiast
Enthusiast
Posts: 744
Joined: Thu Jun 26, 2003 2:09 am
Location: Spain (Galicia)

Post by einander »

I wonder what else this could be useful for.
You can get also Constants and StringConstants addresses.
Thanks helpy: very useful!

Code: Select all

CompilerIf #PB_Compiler_Unicode
  Prototype ptPassStringPointer(String.p-unicode )
CompilerElse
  Prototype ptPassStringPointer(String.p-ascii )
CompilerEndIf

Prototype ptPassLongPointer(Long.L)

Procedure GetStringConstantAddress(*ConstantS) 
  ProcedureReturn *ConstantS
EndProcedure

Procedure GetConstantAddress(*ConstantL) 
  ProcedureReturn *ConstantL
EndProcedure


#ConstS="This is a string 1234567891233456789123456789"
#ConstL=12345678

AddrOfS.ptPassStringPointer=@GetStringConstantAddress()
AddrOfL.ptPassLongPointer=@GetConstantAddress()

PTRS=AddrOfS(#ConstS)
PTRL=AddrOfl(#ConstL)

Debug "String Constant Ptr "+Str(PTRS)  ; OK 
Debug PeekS(PTRS)

Debug "Long Constant Ptr "+Str(@PTRL)   ;OK
Debug PeekL(@PTRL)
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Post by helpy »

1. A constant Number does not have an Datatype! It can be assigned to any variable. Why do you think that the constant #ConstL=12345678 is a long?


2. I am not sure, if constant numbers are stored somewhere in an internal data section like strings. I think this is not the case.

Try this code to test this:

Code: Select all

Prototype ptPassLongPointer(Long.L)

Procedure GetConstantAddress(*ConstantL)
  ProcedureReturn *ConstantL
EndProcedure


#ConstL=12345678
#Const2=23456789

AddrOfL.ptPassLongPointer=@GetConstantAddress()

PTRL=AddrOfl(#ConstL)
Debug "Long Constant Ptr "+Str(@PTRL)   ;OK
Debug PeekL(@PTRL) 

PTRL=AddrOfl(#Const2)
Debug "Long Constant Ptr "+Str(@PTRL)   ;OK
Debug PeekL(@PTRL)
Both constants #ConstL and #Const2 would have the same address! This can not be right!

There is a mistake in your code! Not the pointer of the variable is passed to the function, but the value! Try this code:

Code: Select all

Prototype ptPassLongPointer(Integer)

Procedure GetConstantAddress(ConstantL)
  Debug ConstantL
  ProcedureReturn ConstantL
EndProcedure


#ConstL=12345678
#Const2=23456789

AddrOfL.ptPassLongPointer=@GetConstantAddress()

Debug AddrOfl(#ConstL)
Debug ""
Debug AddrOfl(#Const2)
==> In your code you assign the value of the constant to PTRL (which is an integer variable)! ... the value is returned by the function!
==> With Debug Str(@PTRL) the pointer to the variable PTRL is shown!
==> With PeekL(@PTRL) you get the value of the PTRL variable!

This cannot be used to get the pointer of numerical constants, because (1) the value is passed to function (not the pointer) ... and because (2) numerical constants are never stored in an internal datasection (like strings).


3. For strings it is working as long the behavior of Pseudotypes is not changed! If the string, which is passed to the function, has the same string format (the same pseudotype) as the argument, the pointer to the original string is passed to the function.

If the formats are different the string is converted to the other format (given by the pseudotype). And the pointer to this temporary string is passed to the function ... and is only valid for the function itself.

As long PureBasic does pass the pointer to the original string, if the formats are the same, this "workaround" works. But if this behaviour is changed in the future, this will not work anymore!

The pseudotypes are designed to tell the compiler how to pass strings (and also variants) ... and (if necessary) do a conversion of the data.


cu, helpy
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
User avatar
einander
Enthusiast
Enthusiast
Posts: 744
Joined: Thu Jun 26, 2003 2:09 am
Location: Spain (Galicia)

Post by einander »

@helpy:
My mistake :oops:
Thanks for clarifying and providing excellent examples.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

helpy wrote:A constant Number does not have an Datatype! It can be assigned to any variable.
Well, don't forget the exception of those which ends in '$' :wink:
For example:

Code: Select all

#holala$=12 ; <- error
#holala$="12"; <- well done!
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Psychophanta wrote:Well, don't forget the exception of those which ends in '$'
I think that's more of a compiler check than a datatype.
Post Reply