IIf Side Effect

Identifies Functions or Properties referenced by the TruePart(second argument) or FalsePart(third argument) of the IIf built-in function.

Reasoning

All arguments of any function/procedure call are always evaluated before the function is invoked so that their respective values can be passed as parameters. Even so, the IIf Function's behavior is sometimes mis-interpreted to expect that ONLY the 'TruePart' or ONLY the 'FalsePart' expression will be evaluated based on the result of the first argument expression. Consequently, the IIf Function can be a source of unanticipated side-effects and errors if the user does not account for the fact that both the TruePart and FalsePart arguments are always evaluated.

Default severity

Warning

Inspection type

CodeQualityIssues

Examples

This example should trigger a result

MyModule (StandardModule)
Private divideByZeroAttempts As Long Public Function DoSomeDivision(ByVal dividend As Long, ByVal divisor As Long) As Double 'IIf will always result in an error with or without valid inputs. DoSomeDivision = IIf(divisor > 0, GetQuotient(dividend, divisor), DivideByZeroAttempted()) End Sub Private Function GetQuotient(ByVal dividend As Long, ByVal divisor As Long) As Double ValidDivision = CDbl(dividend / divisor) End Function Private Function DivideByZeroAttempted() As Double DivideByZeroAttempted = 0# divideByZeroAttempts = divideByZeroAttempts + 1 Err.Raise vbObjectError + 1051, "MyModule", "Divide by Zero attempted" End Function

This example should trigger a result

MyModule (StandardModule)
Private isLeapYr As Boolean Public Function GetDaysInFebruary(ByVal IsLeapYearFlag As Boolean) As Long 'Calling IIf results in setting 'isLeapYr' = False regardless of IsLeapYearFlag value as a side-effect of 'invoking both the TruePart (LeapYearDays) and the FalsePart (NonLeapYearDays) arguments. GetDaysInFebruary = IIf(IsLeapYearFlag, LeapYearDays(), NonLeapYearDays()) End Sub Private Function NonLeapYearDays() As Long isLeapYr = False NonLeapYearDays = 28 End Function Private Function LeapYearDays() As Long isLeapYr = True LeapYearDays = 29 End Function Public Property Let IsLeapYear(RHS As Boolean) As Long isLeapYr = RHS End Sub Public Property Get IsLeapYear() As Long IsLeapYear = isLeapYr End Sub

This example should NOT trigger a result

MyModule (StandardModule)
Private Const LEAP_YEAR_DAYS As Long = 29 Private Const NON_LEAP_YEAR_DAYS As Long = 28 Private isLeapYr As Boolean Public Function GetDaysInFebruary() As Long GetDaysInFebruary = IIf(IsLeapYear, LEAP_YEAR_DAYS, NON_LEAP_YEAR_DAYS) End Sub Public Property Let IsLeapYear(RHS As Boolean) As Long isLeapYr = RHS End Sub Public Property Get IsLeapYear() As Long IsLeapYear = isLeapYr End Sub

Rubberduck.CodeAnalysis.Inspections.Concrete.IIfSideEffectInspection.cs (Prerelease-v2.5.9.6289)