I learned to like AND use AND read it, saving space. (Thanks Chris recalling the origin )
So I think too it's dependend from how familiar with this 'mysterious' IIF-statement I'am.
But, what I wanted to ask:
I would be really interested to know, how this IIf-statement is translated in machine code by the compiler!
Somebody who knows?
As shown before (see the instructive Posting #10 from Pat Hartman) there must be a difference between an IIf statement and its 'equal' If-Else solution.
So my question is how the compiler is translating this IIf statement in machine code .
It's been a while, but here's the general idea. Both of the
VBA constructs below would generate roughly the machine code.
I don't want to carry it a step further and assemble that
into machine code.
I think Chris used to work with the PDP-11 computers. This
is sort of MACRO-11.
Code:
IIf(A > B, A, B)
If A > B Then
fnValue = A
Exit Function
ELse
fnValue = B
Exit Function
End If
Start: Mov A, R0
Mov B, R1
Cmp R0, R1
BH MoveA
MoveB: Move R1, (SP)+
RTS PC
MoveA: Move R0, (SP)+
RTS PC
“Of course the priorities change if the code is in a loop that executes multiple times.
The more frequently a piece of code is executed, the more important it is to make it efficient.”
It implies that we should understand just when, where and under what circumstances we do or do not do things in a certain way.
And without that understanding we can not correctly choose between readability and efficiency.
Wayne
I also dislike them when they are complex enough to warrant a second look.
But when they are simple I think the saving of screen real estate can be the deciding factor.
Willi
I’m only on my second cup of coffee so I hope this makes sense: -
Code:
Sub Test()
Dim X As Long
Dim Y As Long
X = 1
Y = 1
MsgBox IIf(False, X / 1, Y / 0)
MsgBox MyTestFunction(X / 1, Y / 0)
End Sub
Function MyTestFunction(A As Long, B As Long) As Long
MsgBox "Here in MyTestFunction"
End Function
If we run these two lines of code they both raise the same division by zero error.
We know that the IIf function will raise the error but strictly speaking it is not raised in the IIf function.
Just like the MyTestFunction function, the error is raised while evaluating the arguments before they are passed to the function.
In the above example MyTestFunction does not execute its MsgBox.
So it seems it’s not the “fault” of the IIf function at all but the argument evaluating mechanism.
This would seem to explain why the IIf function seems to always evaluate both True and False parts.
Not because it’s the fault of the nasty old IIf function but simply because it is a function and all arguments are evaluated before passing.
Hope that makes some sense…now for my third cup of coffee.
fortunately having my 12th cup I think I could follow your explanations. And as I followed it fell like scales just from my hairs: what a stupid, simpletonary and dumpfpfeifentrotteliger* Kraut I am!
Apart from having given today two or three wrong and absolutly foolish advices, I did not thought over that this IIf statement could be just a normal, ordinary and alldaytrivial FUNCTION!
I really feel ashamed of my last question.
Sorry!
But I want thank you and Pat, and Wayne and all the others for your friendly and helpful Postings. To me it has been a very instructive and stimulating Thread.
Thank you all.
And now I will try 'to hold the ball flat'**...
Willi
*sorry, can't translate.
**hope you understand in english
With the conditions as stated above, even the If function behaves the same.
Code:
If Y / 0 Then
MsgBox "You'll never get here."
Else
MsgBox "You'll never get here either."
End If
The moral of the story is, don’t do divisions in arguments that are passed to any function.
In fact, don’t do anything that might cause any error while passing any argument to any function or subroutine.
The argument will simply crash at evaluation, before it gets to the procedure.
The validity of calculated or assignment arguments needs to be evaluated before we attempt to pass them.
The question of which is faster, the IIf or the If function needs to be tested but also requires a little more thought.
If Y / 0 Then, evaluates one passed argument to the If function.
IIf(False, X / 1, Y / 0), has to evaluate three passed arguments to the IIf function.
Which should be faster… and why?
Technically, from a code point of view, the IIf function is no better or worse than any other procedure when evaluating arguments.
For example: -
Code:
Option Explicit
Option Compare Text
Public Declare Function timeGetTime Lib "Winmm.dll" () As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal lngMilliseconds As Long)
Sub Test()
Dim X As Long
Dim lngStart As Long
lngStart = timeGetTime()
X = MyTestFunctionA(DelayMilliseconds(2000))
MsgBox timeGetTime() - lngStart
lngStart = timeGetTime()
X = MyTestFunctionB(DelayMilliseconds(2000), DelayMilliseconds(3000))
MsgBox timeGetTime() - lngStart
End Sub
Function MyTestFunctionA(lngFirstMilliseconds As Long)
' Do nothing.
End Function
Function MyTestFunctionB(lngFirstMilliseconds As Long, lngSecondMilliseconds As Long)
' Do nothing.
End Function
Function DelayMilliseconds(Delay As Long) As Long
Sleep Delay
End Function
MyTestFunctionA takes 2 seconds to evaluate its argument.
MyTestFunctionB takes 5 seconds to evaluate its arguments.
Therefore the question is, “Why is the IIf function so maligned?”
Well, a bit more code is required…
Code:
lngStart = timeGetTime()
If True Then
X = MyTestFunctionA(DelayMilliseconds(2000)) ' < 2 seconds
Else
X = MyTestFunctionA(DelayMilliseconds(3000))
End If
MsgBox timeGetTime() - lngStart
lngStart = timeGetTime()
If False Then
X = MyTestFunctionA(DelayMilliseconds(2000))
Else
X = MyTestFunctionA(DelayMilliseconds(3000)) ' < 3 seconds
End If
MsgBox timeGetTime() - lngStart
But we would never do that... would we?
Well the sad fact is that some people do and that makes some people sad facts.
(But the point is…2 seconds XOR 3 seconds is still better than 5 seconds.)
Now that we understand the technical code point of view AND we only use readable IIf functions then the IIf function has the advantage of screen real estate.
Since, under these circumstances, the IIf function is readable then using it helps to make our whole procedure more readable simply by trying to keep the whole procedure ‘on screen’.
I think I might have to come back and edit this later.
having had a very instructive and enlithening journey on the marvelous land of the disregarded and frequently even calumniated IIF function (Thanks to all) I would like to wash out the ash from my hair and return to the origin starting point throwing my last dump question into the wideness of this very friendly and helpful council:
In a statement like
Code:
IF cond1 AND cond2 AND cond3 THEN ...
why does ACCESS will evaluate all this conditions, even if the first is false?
It is not because it is a function - as in the case of the IIf function - , or I'am wrong once again? Please show mercy....
No…one does not need to invent anything. It has already been invented.
This is difficult to try and explain…
The logical states are defined in hardware…software simply tries to keep pace.
The computer screen you are looking at is running on hardware logic.
The data that is being processed is being processed at a hardware logic level.
The software is trying to translate software instructions to hardware instructions.
Hardware logic governs the system, not the software.
The OR, AND, XOR, NAND, and the like, must be processed within the logical definition of the hardware truth tables.
Those tables will be found in digital electronics books and not necessarily in software books.
Without those digital electronic definitions your computer would not exist.
It does not matter what computer you use, nor what language you may use on that computer, but it must comply with the hardware truth tables.
Some languages may have the intelligence to ‘bail out’ after a False is found in an AND statement. VBA and BASICS do not. But they give you the option to write it in such a way that you achieve the same outcome. You now have the control and the flexibility.