IIF() and argument evaluation - xBase vs. Clipper vs. HB32

470 views
Skip to first unread message

F McKenney

unread,
Apr 10, 2014, 5:41:20 PM4/10/14
to harbou...@googlegroups.com

I'm attempting to port the decompiled source of an ancient Clipper app to Harbour, and while some of the problems I've encountered turned out to be obvious-in-retrospect, this one has me stumped.  I can't tell whether I'm dealing with a real difference between Clipper v.something_or_other and the Harbour Project compiler v3.2, or if I've simply been staring at this uncommented code so long my brain has turned to mush.

Given an expression of the form:

  iif( expr1, expr2, expr3 )

do dBASE, VFP, Clipper, and the Harbour Project compiler differ in how expr3 is evaluated?

Here's why I ask: About six levels deep in this app one function sets up a parameter array like this:

function F_MAINT()

  local afm
  ...
  afill(afm, Nil)
  afm[0] := ...
  afm[11] := 75 // afm[6] and afm[8] are never assigned a value as far as
  ...           // I can tell
  DGMAINT(afm)
  ...

return

function DGMAINT(aparms)

  local otbc

  ...
  otbc:= tbcolumnne(aparms[10], aparms[5])
* otbc:width(iif(aparms[11] != Nil, aparms[11], aparms[8] - ;
     aparms[6] - 1))
  ...

return

The app blows up on the line marked with an asterisk with the folowing
error stack (I've deleted some error-in-error-handler recursion which I
haven't fixed yet):

  Called from WIDTH(0)
  Called from DGMAINT(767) in U_GRANT.prg
  Called from F_MAINT(47) in M_GRANT.prg
  Called from DG_PDMX(312) in DGPSCRN.prg
  Called from DGPULL(201) in DGPSCRN.prg
  Called from USER(326) in hb_g_grant.prg

I stuck a routine just ahead of the error-provoking like and it condifrms my suspicions that at the point of the error it looks like this:

  otbc:width(iif( (75 != Nil), 75, (Nil - Nil - 1) ) )

and that this is the problem:

  iif( (75 != Nil), 75, (Nil - Nil - 1) )

Harbour doesn't like expressions like "1 + Nil", so I'm having trouble understanding why it was coded that way back in 1999.

Let me add one more wrinkle: I know the person who coded this, and he was a fairly good coder, so I'd think that he expected that syntax to work -- for his compiler, and in another century. I _think_ he expected it to behave like this (Cliper-Klutz warning):

 iif( expr1, &"expr2", &"expr3" )

that is, that expr3 would not get executed -- and no error would be triggered -- if aparms[11] was non-Nil.

Then there's the question of how to fix this.  I can replicate the syntax above, but there are a _lot_ of iif() calls in the code (grep|wc reports 426), and even if 10% of them are like this that's a lot of repair work. I don't suppose that there's some secret, undocumented 'hbmk2' parameter that would affect this? Say, -PCCn to set the "perverse code compatibility" level? <grin!>


Time for a break. Any comments or suggestions will be welcomed, and if I've omitted any critical information please let me know.


Frank McKenney
McKenney Associates

Francesco Perillo

unread,
Apr 10, 2014, 5:54:49 PM4/10/14
to harbou...@googlegroups.com
I think there should be something not ok in the code you shown...

Look at this:
PROCEDURE main

   IF 75 != NIL
      ? "true"
   ELSE
      ? "false"
   ENDIF

   ? iif( 75 != NIL, a(), b() )

FUNCTION a

   ? "A"

   RETURN "a"

FUNCTION b()

   ? "B"

   RETURN "b"

In IIF the parameter not returned is never evaluated... this code returns true A a... b() is never called...

And the error is in WIDTH

  Called from WIDTH(0)
  Called from DGMAINT(767) in U_GRANT.prg

This means you called Width() with the wrong parameter... or better yet you called :width on otbc that is an object that has no :Width method...

Unfortunately you didn't report the error message...




--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: http://groups.google.com/group/harbour-users

---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

F McKenney

unread,
Apr 10, 2014, 11:40:29 PM4/10/14
to harbou...@googlegroups.com

Thank you for replying.

The short answer is that I thought I saw where my problem was coming from, I performed a few tests that seemed to confirm it, and got it completely wrong.


On Thursday, April 10, 2014 5:54:49 PM UTC-4, fperillo wrote:
I think there should be something not ok in the code you shown...

There was.
 
In IIF the parameter not returned is never evaluated... this code returns true A a... b() is never called...

And the error is in WIDTH
  Called from WIDTH(0)
  Called from DGMAINT(767) in U_GRANT.prg

This means you called Width() with the wrong parameter... or better yet you called :width on otbc that is an object that has no :Width method...

It turns out that the iif() was working, it was returning a 75, and the code was then attempting the equivalent of this:

  (Nil):width(75)

It seems unlikely that a (the?) Nil object has a "width" instance variable, and the compiled code was perfectly within its rights to reject my inadvertent attempt to give it a value. (Oops.)
 
Unfortunately you didn't report the error message...

No. With the error handler (which needs work) is in place, the message is:

  Unrecoverable error 9003: Too many recursive error handler calls

and without it I see:

  Unrecoverable error 9002: No ERRORBLOCK() for error
 
I'm now trying to figure out which piece of code was supposed to set up a value which which was supposed to invoke something else to make sure a non-Nil TBColumn object was created.

Thank you for getting me "unstuck".


Frank

zbiant

unread,
Apr 11, 2014, 8:34:35 AM4/11/14
to harbou...@googlegroups.com
* otbc:width :=   (iif(aparms[11] != Nil, aparms[11], aparms[8] - ; 
aparms[6] - 1))

F McKenney

unread,
Apr 11, 2014, 4:21:42 PM4/11/14
to harbou...@googlegroups.com
An update:

I found out what was causing my error-in-error-handler recursion in the error handler I installed via ERRORSYS.

Here's the offending line:

      if (!Empty(e:descriptio()))

If Clipper had a 10-character name limit, this would have compiled AND run correctly back in 1999, but compiles and then has a hernia with Harbour (as it should). Once I noticed the error, adding the missing final 'n' fixed it:

      if (!Empty(e:description()))

File as "Porting Clipper to Harbour Project, Cautionary Notes #185"   <grin!>

Oh, and now that it's working properly, it turns out the the error report I would have seen was this:

    BASE/1004  No exported method: WIDTH
    DGMAINT(772)

Sigh.

Anyway, thanks to everyone again for the help.

Frank

Przemyslaw Czerpak

unread,
Apr 11, 2014, 8:07:42 PM4/11/14
to harbou...@googlegroups.com
Hi,

Thank you very much for clarify the problem on public forum.
Hat off.
Believe that it's very unpleasure situation when voluntaries
working on Harbour core code have to clarify perfectly clean
things just to pacify some very strange ideas created by
frustrated users ;-)
IIF() semantic in Harbour is exactly the same as in Clipper.
In some other languages like CLIP IIF() works like function
and usually it's documented.

best regards,
Przemek



On Fri, 11 Apr 2014, F McKenney wrote:
> An update:
>
> I found out what was causing my error-in-error-handler recursion in the
> error handler I installed via ERRORSYS.
>
> Here's the offending line:
>
> if (!Empty(e:descriptio()))
>
> If Clipper had a 10-character name limit, this would have compiled AND run
> correctly back in 1999, but compiles and then has a hernia with Harbour (as
> it should). Once I noticed the error, adding the missing final 'n' fixed it:
>
> if (!Empty(e:description()))
>
> File as "Porting Clipper to Harbour Project, Cautionary Notes #185"
> <grin!>
>
> Oh, and now that it's working properly, it turns out the the error report I
> *would* have seen was this:
>
> BASE/1004 No exported method: WIDTH
> DGMAINT(772)
>
> Sigh.
>
> Anyway, thanks to everyone again for the help.
>
> Frank
>
Reply all
Reply to author
Forward
0 new messages