#constant=?label results in A constant can't be composed by a variable or a function error

Just starting out? Need help? Post your questions and find answers here.
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

#constant=?label results in A constant can't be composed by a variable or a function error

Post by nsstudios »

Hi all,

I was trying to access labels by their names dynamically,so I tried setting a pair of constants that would hold label addresses as runtime (because I assume you can't runtime labels?), but I get the
A constant can't be composed by a variable or a function.
error.
Why does this happen?
Is there a way to do this with constants or another non-variable or non-map solution? I can use variables or maps, but that just seems like a bad idea.
I don't get what the problem is; aren't labels available at compile time?

Code: Select all

EnableExplicit
InitSound()
DataSection
testStart:
IncludeBinary "c:/windows/media/ding.wav"
testEnd:
EndDataSection
#testStart=?testStart
#testEnd=?testEnd
Runtime #testStart, #testEnd
CatchSound(0, GetRuntimeInteger("#testStart"), GetRuntimeInteger("#testEnd")-GetRuntimeInteger("#testStart"))
Any help is much appreciated.
Take care.
BarryG
Addict
Addict
Posts: 3266
Joined: Thu Apr 18, 2019 8:17 am

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by BarryG »

You already said why this happens: trying to get a label name dynamically. Constants can't be changed or assigned dynamically.

BTW, what you're trying to do is the same as what I've done for images in my apps, but I have to use a Global var to do it (due to the constant problem).

I embed my images in a DataSection like so:

Code: Select all

Img_Wrap: : IncludeBinary "Includes\Wrap.ico"
And then assign them a global var like so:

Code: Select all

Global Catch_Img_Wrap=ImageID(CatchImage(#PB_Any,?Img_Wrap)) ; ImageID() is optional here.
Then I just refer to that embedded image in my apps with the "Catch_Img_Wrap" variable.
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by nsstudios »

I currently do it with a variable as well, but don't get why a constant doesn't work. Isn't label known at compile time?
I meant dynamically as in accessing it dynamically through runtime, just like you can do something like

Code: Select all

Runtime Enumeration
#a0=3
#a1
#a2
EndEnumeration
Debug GetRuntimeInteger("#a"+Random(2))
So what you're accessing is non-dynamic, but you can access it dynamically, i.e., by name.
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by Tenaja »

nsstudios wrote: Sun May 09, 2021 3:46 am I currently do it with a variable as well, but don't get why a constant doesn't work. Isn't label known at compile time?
I meant dynamically as in accessing it dynamically through runtime, just like you can do something like

Code: Select all

Runtime Enumeration
#a0=3
#a1
#a2
EndEnumeration
Debug GetRuntimeInteger("#a"+Random(2))
So what you're accessing is non-dynamic, but you can access it dynamically, i.e., by name.
My guess would be because the code is relocatable, allowing operating systems to manage memory. For instance, you might open it up after a fresh reboot, and it'll be in one location, but of it's a long time after the boot, it will be elsewhere. If you don't know the ram location it's going to load into, you cannot know the ram location of the label.
(Not like microcontrollers, or cpu's in the old days, such as the 6502 when you controlled where the code loaded.)
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by Olli »

Tenaja wrote:you cannot know the ram location of the label.
Do not worry about this, even after a long time : your label address will never change, because it is an virtual address.

This means also, even if few occurable, that two different tasks get the same label address value, however these two same addresses does not match to the same physical place.

Code: Select all

hard memory
^
Hard pages
^
Virtualization (soft pages)
^
Coder point of view
User avatar
Sicro
Enthusiast
Enthusiast
Posts: 538
Joined: Wed Jun 25, 2014 5:25 pm
Location: Germany
Contact:

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by Sicro »

Olli wrote: Sun May 09, 2021 11:00 am
Tenaja wrote: you cannot know the ram location of the label.
Do not worry about this, even after a long time : your label address will never change, because it is an virtual address.

Code: Select all

Debug ?text

DataSection
  text:
  Data$ "Text example"
EndDataSection
  • Output on my Linux: 4483176
  • Output on my virtualized Windows 7: 5368956088
But yes, the address does not change when I run the program multiple times in the same OS. However, I would still not rely on that.
Image
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by Olli »

Just consider ?label is a constant which never matches to another thing that the place where you have initially decided to place it. If you need the enumeration provided with the constant, you can use a macro :

Code: Select all

Macro Label(Name)
myLabel# MacroExpandedCount:
Name:
EndMacro

Label(Start)
   A = ?myLabel1
   B = ?Start
Label(Main)
   C = ?myLabel2
   D = ?Main
Label(theEnd)
   E = ?myLabel3
   F = ?theEnd
   Debug A
   Debug B
   Debug C
   Debug D
   Debug E
   Debug F
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by nsstudios »

Wow! I totally forgot about MacroExpandedCount's existence! Thank you, although that still doesn't allow me to access it in a runtime-like way.

That's just the thing; is there any way to make that enumeration an actual runtime enumeration, or any way to make a label runtime?
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by Olli »

No it is unable. Let's imagine every instruction line took 1 memory storage unit, the labels too :

Code: Select all

0 : Debug "Hello"
1 : ThisLabel:
2 :    Debug "I repeat..."
3 :    Goto ThisLabel
I think the JUMP (Goto) is relative :

Code: Select all

0: Debug "Hello"
1: ThisLabel:
2:    Debug "I repeat..."
3:    Do 2 back steps (3 - 2) = 1 to Go to 'ThisLabel'
So the address value of a label is sometimes a relative value, not an explicit and constant value. This is done during the compiling.

The lonely way is detecting all the label names during a pre-process of the compilation, by reading the source file, and inserting a label names array, task that the IDE allows to do.
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: #constant=?label results in A constant can't be composed by a variable or a function error

Post by nsstudios »

I see. Thank you for the clarification. :)
Post Reply