What is meant by 0&, 1& and 2& (1 Viewer)

daryll

Registered User.
Local time
Today, 01:17
Joined
Jan 2, 2018
Messages
49
Hi!

Could somebody tell me please what are the representation of these characters?
0&, 1& and 2&

Thanks
 

jdraw

Super Moderator
Staff member
Local time
Today, 04:17
Joined
Jan 23, 2006
Messages
15,379
Identifier type characters

Visual Basic supplies a set of identifier type characters that you can use in a declaration to specify the data type of a variable or constant. The following table shows the available identifier type characters with examples of usage.
Code:
Identifier type 
character 	Data type 	Example
% 			Integer          Dim L%
& 			Long 		Dim M&
@ 			Decimal		Const W@ = 37.5
! 			Single 		Dim Q!
# 			Double 		Dim X#
$ 			String 		Dim V$ = "Secret"

more info here
 

jleach

Registered User.
Local time
Today, 04:17
Joined
Jan 4, 2012
Messages
308
... and ^ for LongLong in 64bit (not sure if LongPtr has one, being a psuedo-type).

Typically you see this in use either in:

a) old code, though I hesitate to use the world old: it was common in times gone past let's say, or

b) shortcuts for type coersion for API calls to Windows functions, or

c) ensuring that a VBA function such as Mid() returns a string instead of a nullable variant (for most VBA string manipulation functions, there's a $ version as well: Mid$() instead of Mid() guarantees a string return, for example).
 

daryll

Registered User.
Local time
Today, 01:17
Joined
Jan 2, 2018
Messages
49
g table shows the available identifier type characters with examples of usage.
Code:
Identifier type 
character 	Data type 	Example
% 			Integer          Dim L%
& 			Long 		Dim M&
@ 			Decimal		Const W@ = 37.5
! 			Single 		Dim Q!
# 			Double 		Dim X#
$ 			String 		Dim V$ = "Secret"

more info here

How to interpret this code?
Code:
If (lngPos1 > 0&) And (lngpos < Len(strAddress) - 2&) Then
    lngPos2 = InStr(lngPos1 + 1&, strAddress, strcDelimiter)
 End If
 

MarkK

bit cruncher
Local time
Today, 01:17
Joined
Mar 17, 2004
Messages
8,181
Here, try this in the immediate pane...
Code:
? 32767 + 1
...and notice that it causes error 6, overflow. The problem is that both numbers are integers so the result is going to be an integer, but the biggest allowable integer is 32767, which you can test in the immediate pane...
Code:
? Typename(32767)
 Integer
? Typename(1)
 Integer
? Typename(32768) [COLOR="Green"]'here, the type of this number changes to Long[/COLOR]
 Long
So sometimes it makes sense to force a number to a different type, so we can force a number 1 to be Long...
Code:
? Typename(1&)
 Long
So sometimes in a programming language we want to force a literal number to a certain data type, and this would solve our original error if we coerce the 1 to be Long, like...
Code:
? 32767 + 1&
 32768
...which solves the error. And we can check it like this too...
Code:
? Typename(32767 + 1&)
 Long
So all that's happening here...
Code:
If (lngPos1 > 0[COLOR="DarkRed"]&[/COLOR]) And (lngpos < Len(strAddress) - 2[COLOR="darkred"]&[/COLOR]) Then
    lngPos2 = InStr(lngPos1 + 1[COLOR="darkred"]&[/COLOR], strAddress, strcDelimiter)
End If
...is that someone is coercing those numbers, 0, 1, and 2, which would normally be processed as Integers, someone is coercing them to be Longs.
Probably unecessarily, but it doesn't do any harm either.
hth
Mark
 

jleach

Registered User.
Local time
Today, 04:17
Joined
Jan 4, 2012
Messages
308
You can almost think of it as wrapping CLng() around each of the numbers:

Code:
If (lngPos1 > CLng(0)) And (lngPos < Len(strAddress) - CLng(2)) Then...

(it's not exactly the same, but in a high level view it works out to be the same).
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 03:17
Joined
Feb 28, 2001
Messages
27,179
Here is just a little bit extra about coercion. I'm in a brain-dump mood for some reason.

Type coercion (forcing something to a particular type) is not always necessary in an expression. However, when dealing with constants (e.g. the "32767 + 1" case used above) there can be an issue with overflows.

A constant in an expression starts life as the smallest data type that could hold the given constant. So both 32767 and 1 (without coercion) start life as INTEGER variables. We can't actually examine the code generated by the VBA compiler, but if it is like other pseudo-compilers I have seen, it stores all constants as though they were STATIC variables. They have the data types implied by their format and, if not coerced, their size.

The VBA expression analyzer looks at the data types of the components of an expression before it attempts to evaluate it. It "up-types" smaller variables if some of the variables are larger types. So if variable X is declared as LONG, then expression "X + 1" works just fine. The analyzer internally up-types the 1 (which is an INTEGER if not coerced otherwise), so you add a LONG to a LONG and the result is a LONG.

This is also why you can work with mixed integer and SINGLE or DOUBLE variables in an expression. If Z is a DOUBLE, "Z+1" still works because of automatic up-typing.

You can even create expressions with dates and integers since type DATE is merely a typecast of type DOUBLE. If HocDies is of type DATE then you can write "HocDies + 1" to mean the day after the date in the variable.

The situation that makes coercion necessary is that the expression analyzer does the up-type conversion BEFORE it sets up the math instructions. But for the "32767 + 1" case, those constants are "comfortable" as INTEGER variables (=16 bits) so the analyzer has no need to do the "up-type" operation. That leads to an integer overflow because the analyzer doesn't check ahead of time for that possibility. By using "32767+1&" you force the analyzer to up-type one of the variables and the other has to follow suit. As a result, there is no overflow.

Note also that there is an automatic type conversion across the equals sign. That is, if you had Z as a DOUBLE, what would happen (according to what I can make out from the language specification) is that "Z = 32767 + 1&" causes this sequence:

1. Up-type the 1 to LONG by local coercion - the "&"
2. Up-type the 32767 based on its presence in an expression with a LONG
3. Do the math to get LONG 32768
4. Convert the expression value to DOUBLE to match Z, the target, because Z's type CANNOT be coerced. (It was declared DOUBLE so cannot be changed.)

Which means that if you tried to assign our expression to an Integer, call it I, then the expression I = 32676 + 1& would STILL overflow - at the assignment step - because you can't coerce the target variable.

Using CLng or CDbl in an expression has the same effect as local coercion because the data types of the results (returned function values) are as definite as any variable.

Remember our friend I, the INTEGER? You can write "Z = I + 1&" and avoid the overflow. BUT the up-type of I isn't a problem here. Why? Because the language specification clearly states that you can't affect the values of variables on the right-hand side of the assignment statement. Only the left-hand side would be affected. Therefore, the up-type that occurs only affects the temporary copy of I, not the variable itself, because you are not allowed to affect the variable. And the same principle applies to the constants if, as I suspect, they are stored as STATIC constant variables.
 

Users who are viewing this thread

Top Bottom