Iif compile-time return value

Forum for discussion about the documentation project.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Iif compile-time return value

Post by counting_pine »

https://freebasic.net/wiki/KeyPgIif/history
fxm wrote:IIf returns a different numeric or string or UDT value (not a reference) depending of the result of a conditional expression. Its typical use is in the middle of an expression; it avoids splitting it to put a conditional in the middle.
In the particular case where the condition is resolved at compile-time, IIf returns the original expression itself that satisfies the condition (otherwise, it only returns an evaluation of the expression at run-time).
fxm, could you explain the second part?
Are you saying the behaviour is different when the condition is evaluated at compile-time?
Or are you just saying that fbc doesn't bother emitting the expression that won't be used?

e.g.

Code: Select all

print iif(true, expr1, expr2)
Are you saying that this will be resolved to:

Code: Select all

print expr1
I don't understand the Otherwise bit. Are you just saying it doesn't optimise away either of the expressions?

Is there any difference to the program behaviour when the condition is constant, or does it just result in faster/shorter emitted code?
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Iif compile-time return value

Post by fxm »

I now realize that the above description is not very clear.

Therefore I propose a new text:
.....
IIf returns a different numeric or string or UDT value (not a reference) depending of the result of a conditional expression. Its typical use is in the middle of an expression; it avoids splitting it to put a conditional in the middle.

In the particular case where the condition is resolved at compile-time, IIf returns the original expression itself that satisfies the condition (otherwise, it only returns an evaluation of the expression at run-time).

In the particular case where the condition is resolved at compile-time, the entire IIf syntax is literally replaced by the only expression that satisfies the condition.
Otherwise (the condition cannot be resolved at compile-time), IIf only returns an evaluation at run-time of the expression satisfying the condition.
.....
Example (as a consequence):
Dim As Integer x, y
Dim As Integer cond

Iif (true, x, y) = 1 '' compiling is OK
'Iif (cond, x, y) = 1 '' compiling is NOK
Print x, y
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Iif compile-time return value

Post by MrSwiss »

As a new IIf example, I'd propose:

Code: Select all

' IIF_Test01.bas -- 2017-09-05, MrSwiss

Dim As Boolean  flg     ' requires: FBC >= 1.04.0 32/64-bit versions

' IIF() can be used, to display a Boolean any way you want it ...
' instead of: UCase(Str(flg)), for all upper case, which seems 'bulky'
' and, still not giving you the option e.g.: mixed case, etc.

Do                                              ' start main-loop
    flg = Not flg                               ' invert Boolean var: flg
    If flg Then Color 10 Else Color 12          ' TRUE = green | FALSE = red
    Print "flg: "; IIf(flg, "True", "False"),   ' display it the way you choose
    Print "flg: "; IIf(flg, "Yes", "No"),       ' ... just some examples ...
    Print "flg: "; IIf(flg, "On", "Off")        ' here: a Line Feed occures
    Sleep(1000)                                 ' wait a second: 1000 mS
    If csrlin = 24 Then cls : Locate 1, 1       ' clear screen : repos. cursor
Loop Until Len(InKey)                           ' on user action: quit program
Color 7, 0 : Cls                                ' reset default console colors
' ----- EOF -----
Using a Boolean variable (that what it amounts to: result of 'Expression' = True/False).
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Iif compile-time return value

Post by counting_pine »

From the example you've posted, it sounds like you're saying: when the condition is constant, iif may return an Lvalue.

I think this is one of those cases where the behaviour of the compiler should be challenged rather than documented.

I am generally wary of any difference in behaviour that depends on whether a particular expression is deemed by fbc to be constant or not.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Iif compile-time return value

Post by fxm »

Yes, you prefer to consider that this only a compile optimization and not a requirement:

Code: Select all

Dim As Integer x, y
Dim As Integer Ptr px = @x, py = @y
Dim As Integer cond = -1

Iif (true, x, y) = 1 '' compiling is OK, but syntax is not recommended
Print x, y
'Iif (cond, x, y) = 2 '' compiling is NOK
Print x, y

Iif (true, *px, *py) = 3 '' compiling is OK, but syntax is not recommended
Print x, y
'Iif (cond, *px, *py) = 4 '' compiling is NOK
Print x, y

*Iif (true, px, py) = 5 '' compiling is OK, and syntax is recommended
Print x, y
*Iif (cond, px, py) = 6 '' compiling is OK, and syntax is recommended
Print x, y
So I conclude I must suppress the specific behavior description when condition is resolved at compile-time.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Iif compile-time return value

Post by counting_pine »

It would probably be better to write a bug report about it than document it.
I presume it will also cause changes in behaviour if such an expression is passed as a Byref parameter. We don't really want that to happen.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Iif compile-time return value

Post by fxm »

KeyPgIif → fxm [Suppressed specific behavior description when condition is resolved at compile-time]

I don't agree to fill a bug report for the behavior when the condition is already resolved at compile-time, because I consider this behavior rather as a compile optimization.
Any syntax working when condition is solved at run-time only, is similarly working when condition is already resolved at compile-time.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Iif compile-time return value

Post by counting_pine »

FB will treat Lvalues differently from Rvalues in byref expressions.

Code: Select all

function clobberme(byref n as integer) as integer
	function = n*n
	n = 0
end function

dim as integer a = any, n = 42

print n
print clobberme( iif(a = a, n, n) )
print n
The effect of this code depends on whether fbc changes 'a = a' into a constant. That's a bad thing.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Iif compile-time return value

Post by fxm »

Yes.

The simplest would not it be that the compiler outputs an error if the "IIF" condition is resolvable at compile time?
That compile behavior could be similar for example to the one with "IS" (RTTI) when hierarchy is solvable at compile-time:

Code: Select all

Type Parent Extends Object
End type
Type Child Extends Parent
End Type

Dim As Child c
Dim As Object Ptr p = @c

'OK:
Print *p Is Parent

'NOK:
Print c Is Parent
  • error 297: Types have no hierarchical relation in 'Print c Is Parent'
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Iif compile-time return value

Post by counting_pine »

We don't want an error if it's resolvable at compile-time! We just want it to behave the same as if it wasn't resolvable.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Iif compile-time return value

Post by fxm »

- So, you will have to also fill in a bug report for the IS (RTTI) operator!
KeyPgOpIs wrote:.....
The compiler disallows using Is for checks that can be solved at compile-time.
.....
- Workaround for counting_pine's code:

Code: Select all

#define _iif( condition, expr_if_true, expr_if_false ) _
        type<typeof(iif(condition, expr_if_true, expr_if_false))>(iif(condition, expr_if_true, expr_if_false))


function clobberme(byref n as integer) as integer
   function = n*n
   n = 0
end function

dim as integer a = any, n = 42

print n
print clobberme( _iif(a = a, n, n) )
print n
print
print n
print clobberme( _iif(true, n, n) )
print n
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Iif compile-time return value

Post by counting_pine »

I'm not an expert on RTTI, but that looks like a bug, or at least a badly worded error: "types have no hierarchical relation". Clearly c's type is a child of Parent. I'd call that a hierarchical relation.

I've posted a bug report about IIF (#863).
Perhaps the 'c Is Parent' error warrants one as well.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Iif compile-time return value

Post by fxm »

IS (RTTI) operator:
result = expression Is typename
I have already asked dkl about this a few years ago and he replied:
dkl wrote:.....
typename must be a child type of the expression's type. Operator Is only allows checking downwards in the inheritance hierarchy. Upwards checks can be solved at compile-time, and they cause an Types have no hierarchical relation error, for example here:

Code: Select all

type Parent extends Object
end type

type Child extends Parent
end type

dim as Child x
print x is Parent
.....
Then, my others proposals (without response from any admin):
viewtopic.php?p=215088#p215088
viewtopic.php?p=215300#p215300


In both cases ("IIf" and "IS"), my opinion is that the code must work in the same way whatever the real solving instant (at the compile time or at the run time).
I propose to add also a compiler warning when the solving instant is at the compile time ("IIF" or "IS" usage is useless).
Last edited by fxm on Sep 10, 2017 14:59, edited 2 times in total.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Iif compile-time return value

Post by counting_pine »

I won't go any further into the RTTI discussion. I didn't implement it, and I'm not an expert in it.
I don't have a problem, in principle, with IIF and constants. I do have a problem with inconsistent behaviour. From my perspective, the only purpose of a warning would be to say: sorry, the compiler has a bug here.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Iif compile-time return value

Post by dkl »

When I added the compile-time evaluation for iif() I thought it would be neat and could be useful in #if expressions or other kinds of meta-programming. I didn't consider that eliminating the temp var could have unwanted side-effects, as in that Byref example.

Another problem with solving out the iif() and its temp var is that the type promotion part is dropped too; i.e. the result data type will be that of the remaining argument, not the promoted/combined type of both arguments.
Post Reply