Table of Contents

RDC00112 — Implicit narrowing conversion

Severity: Warning  ·  Family: RDC (Rubberduck Core analyzers)  ·  Raised by: ImplicitNarrowingConversionAnalyzer

A value is assigned, passed or returned into a type that holds less than the value's own type, and nothing in the code says that this is meant.

VBA converts silently in these situations (MS-VBAL §5.5.1.2 Let-coercion), and what it does to the value is easy to miss:

  • A Double or Single assigned to a whole-number type is rounded, and a value that is exactly halfway rounds to the even number: 2.5 becomes 2, and 3.5 becomes 4. It is not truncated, and it is not always rounded up.
  • A value that does not fit the destination - 70000 into an Integer, 300 into a Byte - raises run-time error 6 (Overflow), and only when that particular value shows up. The code works with the values it was tried with, and stops with others.

Writing the conversion out - CLng(d), CInt(n), CByte(n) - changes nothing about what is converted, but it states that the loss is meant, and the next reader can tell a decision from an oversight. A conversion that is written out is not reported.

The whole module is checked, including the procedures nothing calls and the branches that never run. A value that is known - a literal, or a constant - that fits the destination and loses nothing is not reported: Dim b As Byte: b = 10 needs no conversion function. One that loses its fraction (n = 2.5) is. One that does not fit at all (b = 300) is not a warning but an error: the line fails every time it runs, and is reported as VBR00006 (Overflow) before the program runs.

How it is raised

Situation Example Resolution
A Double or Single is assigned to a whole-number type. count = ratio, with count As Long and ratio As Double Write the conversion: count = CLng(ratio). Use Int or Fix if rounding is not what is meant.
A wider whole-number type is assigned to a narrower one. small = big, with small As Integer and big As Long Declare small as a Long, or write the conversion: small = CInt(big).
An expression is wider than the variable it is assigned to. result = result + 1, with result As Byte (the sum is an Integer) Declare the variable wide enough, or write the conversion: result = CByte(result + 1).
A value is passed to a ByVal parameter of a narrower type. Show total, where Sub Show(ByVal n As Integer) is given a Long Change the parameter's type, or convert the argument: Show CInt(total).
A function returns a value of a wider type than it is declared with. Probability = 0.25, in a function declared As Single, from a Double constant Declare the function with the type the value has, or convert: Probability = CSng(Threshold).

See also


ACCUEIL • HOME | ℹ️ BIENVENUE • WELCOME | 🧩 BÂTISSONS • BUILD | RD-VBAL | SDK | 🌐 rubberduckvba.ca