Getting address of string constants with @ or ?
-
- Enthusiast
- Posts: 105
- Joined: Wed Jan 18, 2006 7:40 pm
- Location: Hamburg
Getting address of string constants with @ or ?
Hi,
it would be a nice feature to be able to get the address
of a string constant with the @ or ? operator,
so you could pass them to procedures by pointer for example.
Greatings
technicorn
edit:
Just found that you can take the address of a string constant,
but only for the string itself:
a=@"Hello" ; works
#const = "Hello"
a=@#const ; gives a syntax error
it would be a nice feature to be able to get the address
of a string constant with the @ or ? operator,
so you could pass them to procedures by pointer for example.
Greatings
technicorn
edit:
Just found that you can take the address of a string constant,
but only for the string itself:
a=@"Hello" ; works
#const = "Hello"
a=@#const ; gives a syntax error
-
- Addict
- Posts: 841
- Joined: Mon Jun 07, 2004 7:10 pm
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
- tinman
- PureBasic Expert
- Posts: 1102
- Joined: Sat Apr 26, 2003 4:56 pm
- Location: Level 5 of Robot Hell
- Contact:
Re: Getting address of string constants with @ or ?
Until it does you could always use a macro instead of constants for strings:technicorn wrote:it would be a nice feature to be able to get the address
of a string constant with the @ or ? operator,
so you could pass them to procedures by pointer for example.
Code: Select all
Macro const
"Hello"
EndMacro
Procedure.l StrAdr(addr.l)
ProcedureReturn addr
EndProcedure
Debug StrAdr(@"Hello")
Debug StrAdr(@const)
End
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
(WinXPhSP3 PB5.20b14)
-
- Enthusiast
- Posts: 105
- Joined: Wed Jan 18, 2006 7:40 pm
- Location: Hamburg
Thanks tinmann,
but that doesn't help me with my problem.
To make clear what my intention was for this request,
I want to write a program that keeps track of which file and line a procedure is called from.
For lines that is simple, because #PB_Compiler_Line is a numeric constant,
And for the filename you can use #PB_Compiler_File , but it will give you a string,
which isn't very usefull, because stringhandling is to slow,
just having the address of that constant is much easier to handle and
is as unique as the string itself.
But you can't use @ or ? with #PB_Compiler_File, it will give syntax error.
Hope that makes it clearer.
but that doesn't help me with my problem.
To make clear what my intention was for this request,
I want to write a program that keeps track of which file and line a procedure is called from.
For lines that is simple, because #PB_Compiler_Line is a numeric constant,
And for the filename you can use #PB_Compiler_File , but it will give you a string,
which isn't very usefull, because stringhandling is to slow,
just having the address of that constant is much easier to handle and
is as unique as the string itself.
But you can't use @ or ? with #PB_Compiler_File, it will give syntax error.
Hope that makes it clearer.
There is no adress to a stringconstant, the compiler sets the string direct. For this are Constants.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

Re: Getting address of string constants with @ or ?
Hi technicorn,
cu, helpy
If you want to use string constants, than use DataSection!technicorn wrote:it would be a nice feature to be able to get the address
of a string constant with the @ or ? operator,
so you could pass them to procedures by pointer for example.
cu, helpy
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
PB Last Final / Last Beta Testing
-
- Enthusiast
- Posts: 105
- Joined: Wed Jan 18, 2006 7:40 pm
- Location: Hamburg
@ts-soft
There is an address, see this:
Main file "StringConstants_test.pb"
Include file "StringConstants.pbi"
Excerpt of the resulting asm file compiled with /COMMENTED:
Program part:
; Define file1.s, file2.s
;
; file1 = #PB_Compiler_File
MOV edx,_S1
LEA ecx,[v_file1]
CALL SYS_FastAllocateStringFree
; XIncludeFile "StringConstants.pbi"
; file2 = #PB_Compiler_File
MOV edx,_S2
LEA ecx,[v_file2]
CALL SYS_FastAllocateStringFree
;
; MessageRequester("Test", file1+#LF$+file2)
PUSH dword [_PB_StringBasePosition]
MOV edx,dword [v_file1]
PUSH dword [_PB_StringBasePosition]
CALL _SYS_CopyString@0
MOV edx,_S3
CALL _SYS_CopyString@0
MOV edx,dword [v_file2]
CALL _SYS_CopyString@0
INC dword [_PB_StringBasePosition]
PUSH dword _S4
MOV edx,[PB_StringBase]
ADD [esp+4],edx
CALL _PB_MessageRequester@8
POP dword [_PB_StringBasePosition]
Data part:
public _SYS_StaticStringStart
_SYS_StaticStringStart:
_S1: db "StringConstants_Test.pb",0
_S2: db "G:\Projects\PureBasic4\Tests\StringConstants.pbi",0
_S3: db 10,0
_S4: db "Test",0
pb_public PB_NullString
db 0
public _SYS_StaticStringEnd
As you can see, _S1, _S2 are the addresses for the different replacements of #PB_Compiler_File,
_S3 is the #LF$
and _S4 is for the "Test" string used by the MessageRequester
@helpy
Sorry, but that will not solve my problem,
even using a seperate DataSection for the main and every included source
would mean, you have to give different names to labels in the DataSection,
so you can not use a simple construct like this:
TestProc(param1, param2, ..., @#PB_Compiler_File, #PB_Compiler_Line)
so that TestProc() would get it's normal parameter and the pointer to
the filename string that it was called from.
Of course I would use a Macro to call TestProc() which will be replaced
by just the normal call of TestProc() and parameters, without the filename and linenumber in the final application compilation.
I'm asking for this feature, because I want to write a library written in
pure PB (no asm) to keep track of pointer allocation/reallocation/freeing
with the PB functions AllocateMemory() and the like,
because I often use pointers in my programs and I want to make life easier by knowing where the pointer was used last time.
I already have a set of functions that keep track of that, but I want to store the filenames and linenumers with it,
to make it easier to track errors down to the root.
Sorry if that all sounds like rambling to someone else,
maybe it's just importend to me, and I have to find my
one way to solve that problem.
CU
technicorn
There is an address, see this:
Main file "StringConstants_test.pb"
Code: Select all
Define file1.s, file2.s
file1 = #PB_Compiler_File
XIncludeFile "StringConstants.pbi"
MessageRequester("Test", file1+#LF$+file2)
Code: Select all
file2 = #PB_Compiler_File
Program part:
; Define file1.s, file2.s
;
; file1 = #PB_Compiler_File
MOV edx,_S1
LEA ecx,[v_file1]
CALL SYS_FastAllocateStringFree
; XIncludeFile "StringConstants.pbi"
; file2 = #PB_Compiler_File
MOV edx,_S2
LEA ecx,[v_file2]
CALL SYS_FastAllocateStringFree
;
; MessageRequester("Test", file1+#LF$+file2)
PUSH dword [_PB_StringBasePosition]
MOV edx,dword [v_file1]
PUSH dword [_PB_StringBasePosition]
CALL _SYS_CopyString@0
MOV edx,_S3
CALL _SYS_CopyString@0
MOV edx,dword [v_file2]
CALL _SYS_CopyString@0
INC dword [_PB_StringBasePosition]
PUSH dword _S4
MOV edx,[PB_StringBase]
ADD [esp+4],edx
CALL _PB_MessageRequester@8
POP dword [_PB_StringBasePosition]
Data part:
public _SYS_StaticStringStart
_SYS_StaticStringStart:
_S1: db "StringConstants_Test.pb",0
_S2: db "G:\Projects\PureBasic4\Tests\StringConstants.pbi",0
_S3: db 10,0
_S4: db "Test",0
pb_public PB_NullString
db 0
public _SYS_StaticStringEnd
As you can see, _S1, _S2 are the addresses for the different replacements of #PB_Compiler_File,
_S3 is the #LF$
and _S4 is for the "Test" string used by the MessageRequester
@helpy
Sorry, but that will not solve my problem,
even using a seperate DataSection for the main and every included source
would mean, you have to give different names to labels in the DataSection,
so you can not use a simple construct like this:
TestProc(param1, param2, ..., @#PB_Compiler_File, #PB_Compiler_Line)
so that TestProc() would get it's normal parameter and the pointer to
the filename string that it was called from.
Of course I would use a Macro to call TestProc() which will be replaced
by just the normal call of TestProc() and parameters, without the filename and linenumber in the final application compilation.
I'm asking for this feature, because I want to write a library written in
pure PB (no asm) to keep track of pointer allocation/reallocation/freeing
with the PB functions AllocateMemory() and the like,
because I often use pointers in my programs and I want to make life easier by knowing where the pointer was used last time.
I already have a set of functions that keep track of that, but I want to store the filenames and linenumers with it,
to make it easier to track errors down to the root.
Sorry if that all sounds like rambling to someone else,
maybe it's just importend to me, and I have to find my
one way to solve that problem.
CU
technicorn
Can't see any stringconstant, file1 and file2 are variables stored in datasection
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.

- tinman
- PureBasic Expert
- Posts: 1102
- Joined: Sat Apr 26, 2003 4:56 pm
- Location: Level 5 of Robot Hell
- Contact:
How about this then? It seems to work for me, at least the value I get from the two debug statements are the same. You need to watch that you use the correct pseudotype for the string parameter otherwise PB will convert it and cause the address to be different.
I guess if this is going to be part of your own debug logging library you should be able to hide most of this hackery behind a macro in another file or something.
Obviously the best solution would be for the compiler to accept @#const, which seems reasonable if #const is supposed to be replaced with "string" during compilation.
I guess if this is going to be part of your own debug logging library you should be able to hide most of this hackery behind a macro in another file or something.
Code: Select all
Prototype.l StrCheat(sring.p-unicode)
Procedure.l StrAddr(str_addr.l)
ProcedureReturn str_addr
EndProcedure
*foo.StrCheat = @StrAddr()
#const = "Foo"
Debug *foo(#const)
Debug @"Foo"
End
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
(WinXPhSP3 PB5.20b14)
-
- Enthusiast
- Posts: 105
- Joined: Wed Jan 18, 2006 7:40 pm
- Location: Hamburg
Thanks a lot tinman!!
I would have never thought of "miss"-using pseudotypes that way.
Some little enhancement to show it really works:
I can life with the small overhead of the procedure call for now,
as it is only used in testing mode of the program.

I would have never thought of "miss"-using pseudotypes that way.
Some little enhancement to show it really works:
Code: Select all
CompilerIf #PB_Compiler_Unicode
Prototype.l StrCheat(sring.p-unicode)
CompilerElse
Prototype.l StrCheat(sring.p-ascii)
CompilerEndIf
Procedure.l StrAddr(str_addr.l)
ProcedureReturn str_addr
EndProcedure
*foo.StrCheat = @StrAddr()
#const = "Foo"
*p1= *foo(#PB_Compiler_File)
*p2= *foo(#PB_Compiler_File)
Debug *p1
Debug *p2
Debug PeekS(*p1)
Debug PeekS(*p2)
Debug #PB_Compiler_File
End
as it is only used in testing mode of the program.
Code: Select all
Get the address of the file name string:
Debug ?PB_Compiler_File
; Put at the end of every file:
DataSection
PB_Compiler_File:
Data.s #PB_Compiler_File
EndDataSection
-
- Enthusiast
- Posts: 105
- Joined: Wed Jan 18, 2006 7:40 pm
- Location: Hamburg
Sorry. This ought to do the trick:
Code: Select all
Procedure Callback(FileAddress.l)
Debug PeekL(FileAddress) ; Guaranteed to be different for each file
Debug PeekS(PeekL(@FileAddress))
EndProcedure
Prototype ProtoCallbackInterface(FileAddress.s)
Function.ProtoCallbackInterface = @Callback()
Function(#PB_Compiler_File)
- tinman
- PureBasic Expert
- Posts: 1102
- Joined: Sat Apr 26, 2003 4:56 pm
- Location: Level 5 of Robot Hell
- Contact:
Except that it doesn't because PB is still copying your string to a local variable before you get the address. Check out your code using this:Trond wrote:Sorry. This ought to do the trick:
Code: Select all
string.s = "bar"
Debug @string
Function(string)
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
(WinXPhSP3 PB5.20b14)