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
DoubleorSingleassigned to a whole-number type is rounded, and a value that is exactly halfway rounds to the even number:2.5becomes2, and3.5becomes4. It is not truncated, and it is not always rounded up. - A value that does not fit the destination -
70000into anInteger,300into aByte- 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