From: glen herrmannsfeldt on
mecej4 <mecej4.nyetspam(a)operamail.com> wrote:
(regarding statement functions such as)

>>> program asfbug
>>> INTEGER IX,IY,IDIAG,A,B,C
>>> IDIAG(IX,IY) = ((IY-1)* (2*IX-IY+2))/2

> I was afraid this would be the case, since the implication is that anyone
> who calls the sparse symmetric indefinite linear equations solver MA27 from
> the Harwell Library should be careful if the NAG compilers are used.

> The workaround (at least on the older version of NAG F95) is to
> enclose the arguments with an extra set of parentheses.

That is pretty strange. It is common for #define in C, which
does textual substitution such that without the extra parentheses
the expected precedence rules won't apply. That shouldn't happen
in Fortran statement functions, though.

-- glen
From: mecej4 on
glen herrmannsfeldt wrote:

> mecej4 <mecej4.nyetspam(a)operamail.com> wrote:
> (regarding statement functions such as)
>
>>>> program asfbug
>>>> INTEGER IX,IY,IDIAG,A,B,C
>>>> IDIAG(IX,IY) = ((IY-1)* (2*IX-IY+2))/2
>
>> I was afraid this would be the case, since the implication is that anyone
>> who calls the sparse symmetric indefinite linear equations solver MA27
>> from the Harwell Library should be careful if the NAG compilers are used.
>
>> The workaround (at least on the older version of NAG F95) is to
>> enclose the arguments with an extra set of parentheses.
>
> That is pretty strange. It is common for #define in C, which
> does textual substitution such that without the extra parentheses
> the expected precedence rules won't apply. That shouldn't happen
> in Fortran statement functions, though.
>
> -- glen

Quite so. The first thing that came to my mind was the old advice to
surround almost everything in sight with extra () when using C macros.

Let's remember that NAG puts out C, which it runs through GCC.

Here is the intermediate C for IDIAG(A-C,B-C):

Tmp1 = b_ - c_;
# line 8 "dnag.f"
__NAGf90_lio_write_i(&_ioctx_,(((Tmp1 - 1)*(2*a_ - c_ - Tmp1 + 2))/2));

which is obviously where the error occurs.

For the WRITE of the next item, IDIAG((A-C),(B-C)), NAG puts out

Tmp2 = (b_ - c_);
# line 8 "dnag.f"
__NAGf90_lio_write_i(&_ioctx_,(((Tmp2 - 1)*(2*(a_ - c_) - Tmp2 +
2))/2));

So, it appears that it should be enough to write IDIAG((A-C),B-C) _in_
_this_ _case_, but it would be safer to surround every argument of the ASF
with ().

-- mecej4

From: robin on
"mecej4" <mecej4.nyetspam(a)operamail.com> wrote in message news:hrjshs$gsn$1(a)news.eternal-september.org...
| Reinhold Bader wrote:
|
| > Hello,
| >
| > NAG 5.2 (721) on x86_64 also gets this wrong
|
| > Cheers
| > Reinhold
|
| Thank you.
|
| I was afraid this would be the case, since the implication is that anyone
| who calls the sparse symmetric indefinite linear equations solver MA27 from
| the Harwell Library should be careful if the NAG compilers are used.
|
| The workaround (at least on the older version of NAG F95) is to enclose the
| arguments with an extra set of parentheses.

A more-obvious work-around (that doesn't require alteration to every
function reference) is to re-write the statement function as an
internal function.


From: mecej4 on
On 5/2/2010 11:21 PM, robin wrote:
> "mecej4"<mecej4.nyetspam(a)operamail.com> wrote in message news:hrjshs$gsn$1(a)news.eternal-september.org...
> | Reinhold Bader wrote:
> |
> |> Hello,
> |>
> |> NAG 5.2 (721) on x86_64 also gets this wrong
> |
> |> Cheers
> |> Reinhold
> |
> | Thank you.
> |
> | I was afraid this would be the case, since the implication is that anyone
> | who calls the sparse symmetric indefinite linear equations solver MA27 from
> | the Harwell Library should be careful if the NAG compilers are used.
> |
> | The workaround (at least on the older version of NAG F95) is to enclose the
> | arguments with an extra set of parentheses.
>
> A more-obvious work-around (that doesn't require alteration to every
> function reference) is to re-write the statement function as an
> internal function.
>
>

Certainly.

I should have made it clear that the successful workaround was to
surround the _formal_ ("dummy") arguments in the ASF declaration with
parenthesis, as in

IDIAG(IX,IY) = (((IY)-1)* (2*(IX)-(IY)+2))/2

rather than in multiple invocations of the ASF.

MA27 has been here since the 1980s, and is entirely in Fortran-77.

-- mecej4

From: glen herrmannsfeldt on
mecej4 <mecej4_no_spam(a)operamail.com> wrote:
(snip)

> I should have made it clear that the successful workaround was to
> surround the _formal_ ("dummy") arguments in the ASF declaration with
> parenthesis, as in

> IDIAG(IX,IY) = (((IY)-1)* (2*(IX)-(IY)+2))/2

> rather than in multiple invocations of the ASF.

The tradition for #define is to surround each argument, and
the whole expression, with parentheses. The latter is needed
in the place where the substitution is made.

To see the power, or lack thereof, of #define, there have been
stories of former PASCAL programmers doing:

#define BEGIN {
#define END }

There is no requirement for matching parentheses, brackets,
or braces in the substituted text.

> MA27 has been here since the 1980s, and is entirely in Fortran-77.

-- glen