Can't put adress of label into a static

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Can't put adress of label into a static

Post by Trond »

Code: Select all

Procedure T()
  Static *Table.Character = ?Table
  Table:
EndProcedure
?Table can be computed at compile time. Is it a bug?
Last edited by Trond on Thu Jun 11, 2009 9:10 pm, edited 1 time in total.
dell_jockey
Enthusiast
Enthusiast
Posts: 767
Joined: Sat Jan 24, 2004 6:56 pm

Post by dell_jockey »

will an address fit into a '.Character' variable?
cheers,
dell_jockey
________
http://blog.forex-trading-ideas.com
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

It was a typo, I forgot the *.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

Constants work and the Help also states it has to be a constant value, not a literal value.

but since the compiler works one-pass, adresses of labels later in the code can't be known in this step.

you also can't assign a label to a constant.


... I guess you'll need to screw a workaround.
oh... and have a nice day.
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Post by eesau »

Kaeru Gaman wrote:but since the compiler works one-pass, adresses of labels later in the code can't be known in this step.
That's not true, this works:

Code: Select all

Debug ?Label

Label:
... because it's FASM that gets the address, not PB. Also, Trond's code works if Protected is used.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

eesau wrote:
Kaeru Gaman wrote:but since the compiler works one-pass, adresses of labels later in the code can't be known in this step.
That's not true, this works:

Code: Select all

Debug ?Label

Label:
... because it's FASM that gets the address, not PB. Also, Trond's code works if Protected is used.
It also works like this:

Code: Select all

Global *Table.Character = ?Table

Procedure T()
  Shared *Table.Character
  Table:
EndProcedure
or like this:

Code: Select all

Procedure T()
  Static *Table.Character
  If *Table = 0
    *Table = ?Table
  EndIf
  
  Table:
EndProcedure
The hangup is that Static can only accept a literal or defined constant. If it could accept a computed constant (determined at compile time) it would work with your first example Trond. It isn't directly limited by label's.

You can't assign a label to a defined constant either (i.e. #constant = ?Table), I tried. Label's fall into the category of a variable whose value is determined at compile-time. As eesau pointed out they're value is determined by FASM and not PB.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

The hangup is that Static can only accept a literal or defined constant. If it could accept a computed constant (determined at compile time) it would work with your first example Trond. It isn't directly limited by label's.
No, it is in fact directly limited by labels. I don't understand what you're saying. It works with every other constant in scope except labels.

See?

Code: Select all

Procedure Test()
  Static M = #PI + 5.5
EndProcedure
Label's fall into the category of a variable whose value is determined at compile-time.
They are not variables! They can't ever vary, they are constants. And since they are determined at compile time there is no real reason they can't be used with Static variables.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Trond wrote:
The hangup is that Static can only accept a literal or defined constant. If it could accept a computed constant (determined at compile time) it would work with your first example Trond. It isn't directly limited by label's.
No, it is in fact directly limited by labels. I don't understand what you're saying. It works with every other constant in scope except labels.

See?

Code: Select all

Procedure Test()
  Static M = #PI + 5.5
EndProcedure
Label's fall into the category of a variable whose value is determined at compile-time.
They are not variables! They can't ever vary, they are constants. And since they are determined at compile time there is no real reason they can't be used with Static variables.

It's easy to understand, let me attempt a better explanation.

*Disclaimer: the following details about PureBasic are theorized and not known as fact.

Ignoring procedures for the moment, why does this code fail when using using constants?

Code: Select all

m = #MyConstant + 5.5
#MyConstant = 12
It fails because PureBasic is a one-pass compiler, the constant needs to be defined before it's used.

If that's true (with constants) than why does the following compile?

Code: Select all

m = ?Table + 5

DataSection
  Table:
  Data.l 1,2,3
EndDataSection
It compiles because labels are "special variables." The compiler set's aside space for them when they are first encountered even though it doesn't know their value yet. It knows their value will never change, but unlike an undefined constant, it doesn't know the value yet. Unlike other variable it knows what the type (and thus size) that the value will be. The value is defined as a label and the label is placed in the compiled code (which will be run later on a multi-pass assembler) at that point. When the label definition is encountered later it is added to the DataSection portion that will be added at the end, after all the compiled code.

The same process happens even when a label definition appears before it's first use.

What does this mean? Labels can be thought of as either "special constants" or "special variables". They do not receive a constant value by the compiler, they receive it from the assembler.

If that failed to make sense or you simply think I missed the boat (wouldn't be the first time I did), I'll leave the matter as it is and wish you well in solving it.:wink:

I think what you are needing is a feature request.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

*Disclaimer: the following details about PureBasic are theorized and not known as fact.
You can get the actual facts from the asm file, and your description of what happens isn't right. There is no space allocated to store the value of the label.
In this code:

Code: Select all

var = ?label
label:
PB turns ?label into l_label and label into l_label as well, like this:

Code: Select all

mov dword [v_var], l_label
l_label:
Then the assembler replaces l_label with the address of l_label: (which is simply a number).

This is the same code that is generated for numbers (var = 123):

Code: Select all

mov dword [v_var], 123
But not the same code that is generated for variables (var = othervar), which have space set aside for them. They have to be moved onto the cpu first:

Code: Select all

mov ecx, dword [v_othervar]
mov dword [v_var], ecx
Thus it's not possible to use this form for Static.

When the compiler sees (Static varname = 123) it currently writes this to the near end of the asm file:

Code: Select all

s_Procname.v_varname dd 123
All that is needed to support this feature is to replace ?nameoflabel (used instead of 123) with l_nameoflabel for (Static varname = ?nameoflabel):

Code: Select all

s_Procname_v_varname dd l_nameoflabel
In that case it would work.
I think what you are needing is a feature request.
Which is why I posted this in a forum called "Feature Requests and Wishlists". :)
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Trond wrote:When the compiler sees (Static varname = 123) it currently writes this to the near end of the asm file:

Code: Select all

s_Procname.v_varname dd 123
All that is needed to support this feature is to replace ?nameoflabel (used instead of 123) with l_nameoflabel for (Static varname = ?nameoflabel):

Code: Select all

s_Procname_v_varname dd l_nameoflabel
In that case it would work.
I think what you are needing is a feature request.
Which is why I posted this in a forum called "Feature Requests and Wishlists". :)
I agree. I think if this was implemented as you described it would take some of the rough edges off that are still present with using labels.

Regarding the comment on forums, I was distracted by the "I think this is a bug" part of your first post.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I'm convinced by the argumentation. :D

should be possible to implement and would be a nice feature.
oh... and have a nice day.
Post Reply