Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean if a number is written in square brackets like [5]

Tags:

vba

I am working on an legacy VBA/Excel app and stumbled over some lines of code where a long string (read from a file) is cut into pieces. Those lines look like this:

 Range("E16").Value = Mid(line, 49, [6])

Obviously, writing [6] means taking 6 characters, but I never saw this syntax to put square brackets around a number.

I did some tests and found out that putting those square brackets doesn't do any obvious to the number

Dim x As Double
x = 5.1
Debug.Print [2], [3.1], [-5], x
Debug.Print [3.1] * [x] * [-5]

>>  2             3.1          -5             5.1 
>> -79.05 

So, no truncation, no rounding, no abs-value.
I did some more tests to check if it does some magic similar to putting parentheses around a variable to prevent modifying a value that is passed by reference, but that's not the case:

    x = 5.1: test2 x: Debug.Print x
    x = 5.1: test2 (x): Debug.Print x
    x = 5.1: test2 [x]: Debug.Print x

Sub test2(ByRef y As Double)
    y = y * 2
End Sub

>> 10.2 
>> 5.1
>> 10.2

Surprised that the compiler even accepts this syntax: What is the meaning of using those brackets?

like image 471
FunThomas Avatar asked Feb 07 '19 17:02

FunThomas


1 Answers

Square brackets in VBA/VB6 are used for accessing "foreign identifiers", i.e. identifiers that would otherwise not be legal. For example:

Public Enum Foo
    Some
    Thing
    [Some Thing] ' please don't do this
End Enum

And hidden members whose name begins with an underscore:

Public Property Get NewEnum() As IUnknown
    Set NewEnum = myCollection.[_NewEnum]
End Property

However in the context of the code in this question, the square brackets are, as Scott indicated, essentially shorthand notation for [_Global].Evaluate, which ultimately resolves to Application.Evaluate... assuming we're not in a Worksheet module's code-behind, in which case it's shorthand for Worksheet.Evaluate - and both return a Variant, which means any chained member calls are blind, late-bound calls resolved at run-time: Option Explicit can't save you from a typo.

That's why Rubberduck (an open-source VBIDE add-in project I manage / contribute to) resolves them as "runtime expressions":

Rubberduck's context-sensitive toolbar showing 'A1' as a 'runtime expression'

In other words this:

Range("E16").Value = Mid(line, 49, [6])

Could just as well be written like this:

[E16] = Mid(line, [49], [6])

...which is arguably terrible code with a ton of redundant implicit operations going on.

There is never, NEVER any reason whatsoever to square-bracket an integer literal: it's nothing more than a rather roundabout way to turn an Integer literal into a Double (since worksheet numeric values are Variant/Double):

Debug.Print TypeName(42)
Integer

Debug.Print TypeName([42])
Double

Which is much better off done with an explicit conversion:

Debug.Print TypeName(CDbl(42))
Double

...or even with a (gasp) type hint:

Debug.Print TypeName(42#)
Double
like image 176
Mathieu Guindon Avatar answered Sep 23 '22 01:09

Mathieu Guindon