2

VBA implicitly converts values to Variant as needed, so what would be a use case of the CVar function? In the example given in the documentation, the call to CVar is obviously redundant.

To be precise, I am looking for a concrete, minimal VBA code example, which

  • compiles, but
  • won't compile (or produce a different output) when (only!) CVar(...some expression...) is replaced by ...some expression....

I haven't been able to find such an example, but maybe the someone else can.

Heinzi
  • 167,459
  • 57
  • 363
  • 519

2 Answers2

2

I cannot think about a real life usage for the following, but at least it shows that you could need the function:

Sub test()
    Dim myInt As Integer
    myInt = 2
    ' The following call will throw a runtime error in testSub
    Call testSub(myInt)   
    ' That's okay
    Call testSub(CVar(myInt))
End Sub

Sub testSub(ByRef p As Variant)
    Debug.Print "P: " & VarType(p)
    p = "ABC"
End Sub
FunThomas
  • 23,043
  • 3
  • 18
  • 34
  • 1
    A good one, I expected it to raise a compile time byref mismatch which it does not. But this kind of problems are usually [worked around](https://stackoverflow.com/a/10262247/11683) with `Call testSub((myInt))`. – GSerg Nov 14 '18 at 10:22
  • 1
    In your example `myInt` is also passed as `Variant`, but [with `VT_BYREF`](https://stackoverflow.com/a/31637346/11683). The `()` remove that flag. It's an interesting subject with interesting results, e.g. see https://stackoverflow.com/q/52686198/11683. – GSerg Nov 14 '18 at 10:35
  • @GSerg: Just for curiosity: Do you know any way to read the VT-Flags within VBA? – FunThomas Nov 14 '18 at 10:47
  • Yes, read the first two bytes starting at `VarPtr(that_variable)`. An example: https://stackoverflow.com/a/43554246/11683 – GSerg Nov 14 '18 at 10:49
2

Not sure if that qualifies, but the only thing I can think of is the interaction with As Any in Declare.

Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
  (Destination As Any, source As Any, ByVal Length As Long)

Sub Test()
  Dim source As Long, dest As Long

  source = 42

  CopyMemory dest, CVar(source), 4
  MsgBox dest

  CopyMemory dest, source, 4
  MsgBox dest
End Sub
GSerg
  • 76,472
  • 17
  • 159
  • 346
  • Nice one! I thought about overloading, but rejected the idea, since VBA itself does not support it, and completely forgot about overload *consuming* with `As Any`. – Heinzi Nov 14 '18 at 13:07