mth@cci632.UUCP (Michael Hickman) (11/13/90)
I have upgraded all of our machines to 10.3. Last night a user tried running a program I had written that generates a cross reference list of nets on a PCB. After the program ran all night (should have taken < 15 mins.) I killed it figuring it needed to be recompiled under 10.3. The program compiled fine, but when I ran it, it barfed with an 'reference to illegal address (OS/MST manager)' on this: while not((this_net = nil) or ((this_net^.plusminus = net.plusminus) and (this_net^.net_name = net.net_name))) do Looks like it tried evaluating the expression after the 'or' when the pointer was nil. I changed it to this: while ((this_net <> nil) and not((this_net^.plusminus = net.plusminus) and (this_net^.net_name = net.net_name))) do It liked this, and the program ran. However, another function that uses the EXACT same line as example #1 above works fine with no changes. Compilier optimization level made no difference. It bothers me that it worked fine before, but doesn't now. I'm certainly no programming guru, so if anyone can shed some light on this, please do. Otherwise, this is just another example of Apollo's great compilier technology..... Michael T. Hickman mth@cci.com CAE/CAD Systems Administrator Computer Consoles Inc. Rochester, NY (716)482-5000 x2913
rees@pisa.ifs.umich.edu (Jim Rees) (11/14/90)
In article <43023@cci632.UUCP>, mth@cci632.UUCP (Michael Hickman) writes:
It bothers me that it worked fine before, but doesn't now. I'm certainly
no programming guru, so if anyone can shed some light on this, please do.
Otherwise, this is just another example of Apollo's great compilier
technology.....
It doesn't take a programming guru to realize that when you de-reference a
null pointer, you get what you deserve, and it isn't going to be the same
thing from machine to machine or even release to release of the same
operating system.
There are plenty of things to rag on Apollo about, but this isn't one of
them.
nazgul@alphalpha.com (Kee Hinckley) (11/14/90)
In article <43023@cci632.UUCP> mth@cci.com (Michael Hickman) writes: > while not((this_net = nil) or > ((this_net^.plusminus = net.plusminus) and > (this_net^.net_name = net.net_name))) do > >Looks like it tried evaluating the expression after the 'or' when the pointer >was nil. I changed it to this: ... >guru, so if anyone can shed some light on this, please do. Otherwise, this is just >another example of Apollo's great compilier technology..... I wouldn't knock Apollo's compilers quite so fast. The generate pretty good code, even if they do take forever to do it. But any way, I believe you have run into a feature of Pascal. Namely that the order of expression evaluation is not guaranteed. It's been a while, but I believe that Apollo's Pascal has an 'andthen' operator for just such cases, I assume there's something equivalent for 'or', but I don't recall what. Presumably 10.3 added some compiler optimization or some such that made it decide it was faster to interpret the expression some other way. Now why you went into an infinite loop is another problem. That definitely sounds like a bug somewhere. -- Alphalpha Software, Inc. | motif-request@alphalpha.com nazgul@alphalpha.com |----------------------------------- 617/646-7703 (voice/fax) | Proline BBS: 617/641-3722 I'm not sure which upsets me more; that people are so unwilling to accept responsibility for their own actions, or that they are so eager to regulate everyone else's.
kumorek@apollo.HP.COM (James Kumorek) (11/14/90)
In article <43023@cci632.UUCP>, mth@cci632.UUCP (Michael Hickman) writes: |> |> I have upgraded all of our machines to 10.3. Last night a user tried running |> a program I had written that generates a cross reference list of nets on a PCB. |> |> After the program ran all night (should have taken < 15 mins.) I killed it |> figuring it needed to be recompiled under 10.3. The program compiled fine, |> but when I ran it, it barfed with an 'reference to illegal address (OS/MST |> manager)' on this: |> |> while not((this_net = nil) or |> ((this_net^.plusminus = net.plusminus) and |> (this_net^.net_name = net.net_name))) do |> |> Looks like it tried evaluating the expression after the 'or' when the pointer |> was nil. I changed it to this: |> |> while ((this_net <> nil) and |> not((this_net^.plusminus = net.plusminus) and |> (this_net^.net_name = net.net_name))) do |> |> It liked this, and the program ran. However, another function that uses the EXACT |> same line as example #1 above works fine with no changes. Compilier optimization |> level made no difference. |> |> It bothers me that it worked fine before, but doesn't now. I'm certainly no programming |> guru, so if anyone can shed some light on this, please do. Otherwise, this is just |> another example of Apollo's great compilier technology..... I don't think that Pascal defines the order in which a logical expression is evaluated (unlike C, which defines the order to be from left to right). Thus, in the code 'if (foo_ptr <> nil) and (foo_ptr^.boolean_value) then...', if the compiler descides that it is more efficient to generate code for the second part of the logical expression first, then that's what it will do. Note that the optimiser changes from compiler release to compiler release, so that it may put out code in different orders from earlier releases. In order to get around this deficiency in the Pascal language, Apollo defined the operators 'AND THEN' and 'OR ELSE'. These operators ensure that the evaluation order is from left to right. Thus, to recode my little example: if (foo_ptr <> nil) and then (foo_ptr^.boolean_value) then ... One could argue that the compiler could have been smart enough to realize that other parts of the expression were dereferencing the pointer that is being checked in the first part of the expression; however, there are probably lots of less 'ovious' cases where this would be difficult. Also, the more checks that the compiler tries to do against 'incorrect' uses of language 'features', the slower the compiler will be, and I suspect the last thing our customers want is even slower compilers! :-> Hope this helps.... Jim Kumorek Apollo Computer, Inc. - A subsidiary of Hewlett Packard kumorek@apollo.hp.com
rehrauer@apollo.HP.COM (Steve Rehrauer) (11/14/90)
In article <43023@cci632.UUCP> mth@cci.com (Michael Hickman) writes: >I have upgraded all of our machines to 10.3. Last night a user tried running >a program I had written that generates a cross reference list of nets on a PCB. > >After the program ran all night (should have taken < 15 mins.) I killed it >figuring it needed to be recompiled under 10.3. The program compiled fine, >but when I ran it, it barfed with an 'reference to illegal address (OS/MST >manager)' on this: > > while not((this_net = nil) or > ((this_net^.plusminus = net.plusminus) and > (this_net^.net_name = net.net_name))) do > >Looks like it tried evaluating the expression after the 'or' when the pointer >was nil. I changed it to this: > > while ((this_net <> nil) and > not((this_net^.plusminus = net.plusminus) and > (this_net^.net_name = net.net_name))) do > >It liked this, and the program ran. However, another function that uses the EXACT >same line as example #1 above works fine with no changes. Compilier optimization >level made no difference. > >It bothers me that it worked fine before, but doesn't now. I'm certainly no programming >guru, so if anyone can shed some light on this, please do. Otherwise, this is just >another example of Apollo's great compilier technology..... Lord knows I'm no Pascal semantics guru. However, your code looks a bit bogus. Pascal OR & AND boolean operators will evaluate both operands. Even though your intent was clearly to say "If non-NIL pointer, then if...", this isn't how your program will be interpreted by the compiler. In many circumstances, the compiler will be able to determine that evaluation of the second operand is unnecessary, but you aren't guaranteed that behaviour. Since you've upgraded to sr10.3, and presumably have an 8.7 Pascal compiler, though, there is hope. :-) Rather than standard OR & AND operators, you could "OR ELSE" & "AND THEN", which *do* guarantee short-circuited evaluations. For example, this Pascal snippet: IF ( ( ptr = NIL ) OR ELSE ( ptr^.intval <> 0 ) ) THEN is intuitively the same as (but more compact to write than!): IF ( ptr <> NIL ) THEN IF ( ptr^.intval <> 0 ) THEN Or, the example could've been written with "AND THEN", as: IF ( ( ptr <> NIL ) AND THEN ( ptr^.intval <> 0 ) ) THEN If I were to attempt to rewrite your example snippet using "OR ELSE" & "AND THEN", it'd probably come out looking like: WHILE ( ( this_net <> NIL ) AND THEN ( ( this_net^.plusminus = net.plusminus ) AND ( this_net^.net_name = net.net_name ) ) ) DO Hope that helps. -- "I feel lightheaded, Sam. I think my | (Steve) rehrauer@apollo.hp.com brain is out of air. But it's kind of | The Apollo Systems Division of a neat feeling..." -- Freelance Police | Hewlett-Packard
beierl_c@apollo.HP.COM (Christopher Beierl) (11/14/90)
In article <43023@cci632.UUCP> mth@cci.com (Michael Hickman) writes: > ... The program compiled fine, >but when I ran it, it barfed with an 'reference to illegal address (OS/MST >manager)' on this: > > while not((this_net = nil) or > ((this_net^.plusminus = net.plusminus) and > (this_net^.net_name = net.net_name))) do > >Looks like it tried evaluating the expression after the 'or' when the pointer >was nil. I changed it to this: > > while ((this_net <> nil) and > not((this_net^.plusminus = net.plusminus) and > (this_net^.net_name = net.net_name))) do > Pascal does NOT guarantee short-circuit evaluation of Boolean expression in an IF statement as C does. You MUST use the second form at all times to avoid the possibility of attempted to dereference a nil pointer. See "Domain Pascal Language Reference", Chapter 4 "Code", p4-93 which talks about the IF statement. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Christopher T. Beierl Internet: beierl_c@apollo.HP.COM;beierl_c@apollo.com Apollo Computer, Inc. UUCP: {mit-eddie,yale,uw-beaver}!apollo!beierl_c A Subsidiary of Hewlett-Packard Phone: (508) 256-6600
rehrauer@apollo.HP.COM (Steve Rehrauer) (11/15/90)
In article <4e00f7c8.20b6d@apollo.HP.COM> rehrauer@apollo.HP.COM (Steve Rehrauer) writes: >For example, this Pascal snippet: > > IF ( ( ptr = NIL ) OR ELSE ( ptr^.intval <> 0 ) ) THEN > >is intuitively the same as (but more compact to write than!): > > IF ( ptr <> NIL ) THEN > IF ( ptr^.intval <> 0 ) THEN Oh, sigh -- let me try again. This: IF ( ( ptr = NIL ) OR ELSE ( ptr^.intval <> 0 ) ) THEN { statements } is the same as this: IF ( ptr = NIL ) THEN { statements } ELSE IF ( ptr^.intval <> 0 ) THEN { statements } Read the manual for details. (Do what I mean, not what I say. :) -- "I feel lightheaded, Sam. I think my | (Steve) rehrauer@apollo.hp.com brain is out of air. But it's kind of | The Apollo Systems Division of a neat feeling..." -- Freelance Police | Hewlett-Packard