Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Wrong code, I could not find the error

1 view
Skip to first unread message

utab

unread,
Feb 1, 2008, 12:20:28 PM2/1/08
to
Dear all,

What is wrong in the below code:

PROGRAM MAIN

IMPLICIT NONE

real :: a,b,c

a=1.0
b=2.0
c=3.0

print*, a
print*, b
print*, c

call mistaken(a=2.0,c=3.0)

print*, a
print*, b
print*, c

CONTAINS

subroutine mistaken(a,b,c)
real, intent(inout) ::a
real, intent(out), optional :: b
real, intent(in) :: c
a=2*c*b
if(present(b)) b=2*a
end subroutine mistaken


END PROGRAM MAIN

My best,

Umut

Sebastian Gallinat

unread,
Feb 1, 2008, 12:52:34 PM2/1/08
to
utab schrieb:

> Dear all,
>
> What is wrong in the below code:
>
> PROGRAM MAIN
>
> IMPLICIT NONE
>
> real :: a,b,c
>
> a=1.0
> b=2.0
> c=3.0
>
> print*, a
> print*, b
> print*, c
>
> call mistaken(a=2.0,c=3.0)

Here is a uses as a parameter, but in subroutine mistaken declared as
intent (in out). This should be:

a=2.0
call mistaken(a,c=3.0)

>
> print*, a
> print*, b
> print*, c
>
> CONTAINS
>
> subroutine mistaken(a,b,c)
> real, intent(inout) ::a
> real, intent(out), optional :: b
> real, intent(in) :: c

> a=2*c*b

b is an optional argument and not part of your procedure call
mistaken(a,c=3.0).

> if(present(b)) b=2*a
> end subroutine mistaken
>
>
> END PROGRAM MAIN
>
> My best,
>
> Umut

Hope, this helps, Sebastian.

Richard Maine

unread,
Feb 1, 2008, 1:08:14 PM2/1/08
to
utab <umut....@gmail.com> wrote:

> What is wrong in the below code:

Two things... at least. Perhaps a third.

1. It doesn't include an indication of why *YOU* think something is
wrong with it. When asking things like that, you should include the
symptoms that you observed - not just the code. Does the compiler fail
to compile this? If so, what error messages does it give? Does it
compile but do unexpected things when executed? If so, say what was
expected and what happened. There is certainly more data than just "code
is wrong". About the only way you could get that poor a diagnostic
message would be if you showed it to a tutor who was feeling
particularly unhelpful. You won't get that message from the computer.
(You might possibly get one even more obscure - such as "segmentation
error", but you won't get "wrong code".)

2.

> call mistaken(a=2.0,c=3.0)
...
...


> subroutine mistaken(a,b,c)
> real, intent(inout) ::a

The dummy argument "a" is intent(inout). For an intent(inout) dummy, the
actual argument has to be "defineable". That is, it has to be something
whose value is allowed to change. The "out" part implies that. The
literal constant 2.0 is not allowed to change in this way.

3. Not actually an error in your code, but something that might indicate
confusion in your understanding of it. The 3 variables "a,b,c" in the
main program seem to have no role in the code. You declare them, assign
them values, and then print them out, but they have nothing to do with
the subroutine. If you think that they have anything to do with the
arguments to the subroutine, then you are confused. They are unrelated
other than in that they have the same name. I advise against such reuse
of the same name in a context like this. It is confusing... and I'm
suspicious that it might be confusing you.

Much more could be said about point 3 here, but since you didn't provide
any information about what problem(s) you are seeing or what you are
trying to do, I don't see much point in spending more time in
elaborating on something that might not even be needed. I'm just
suspicious of confusion.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain

Richard Maine

unread,
Feb 1, 2008, 1:12:18 PM2/1/08
to
Sebastian Gallinat <sebastian...@arcor.de> wrote:

> > call mistaken(a=2.0,c=3.0)
>
> Here is a uses as a parameter,

Please, no, don't add to a common confusion by misusing the term
"parameter" in this way. No, "a" is not a parameter. I realize that this
looks a lot like part of the syntax of a PARAMTER statement, but that's
not what it is.

(I agree with the underlying issue that you are talking about - see my
simultaneous post - just not with the terminology that you use to
describe it.)

e p chandler

unread,
Feb 1, 2008, 2:09:31 PM2/1/08
to

1. Your subroutine changes the value of the variable A. It also
receives a value for A. So it must be intent INOUT. However,

call mistaken(a=2.0,c=3.0)

does NOT do what you think it does. It does NOT assign a value of 2.0
to A, then call the subroutine. It calls the routine with what is in
effect a value of 2.0.

You need to assign 2.0 to A, then call the routine with A as a regular
argument:

A=2.0
call mistaken(a,c=3.0).

2. Even with #1 taken care of, what is the value of B when there is no
argument corresponding to B? Where is the variable stored? What value
is assigned to A?

As written, the program's behavior is undefined. On my system, using
g95 under XP, it gives an access violation.

Perhaps you want something like:

if (.not. present(b)) b=1.23456

--- e

glen herrmannsfeldt

unread,
Feb 1, 2008, 2:42:56 PM2/1/08
to
Richard Maine wrote:

> utab <umut....@gmail.com> wrote:

>>What is wrong in the below code:

> Two things... at least. Perhaps a third.

> 1. It doesn't include an indication of why *YOU* think something is
> wrong with it. When asking things like that, you should include the
> symptoms that you observed - not just the code.

It looks to me like it might have been given as a homework or even
quiz problem, where one is supposed to explain it without running it
on a computer.

As someone else said,

call mistaken(a=2.0,c=3.0)

does not change the values of a or c, as, for
example, a C programmer might expect.

The value of 2.0 might change, though.

-- glen

Ron Shepard

unread,
Feb 1, 2008, 3:11:09 PM2/1/08
to
In article
<6cd834f4-26d3-4c14...@s8g2000prg.googlegroups.com>,
e p chandler <ep...@juno.com> wrote:

> A=2.0
> call mistaken(a,c=3.0).

Perhaps the following would clarify what is happening. The above is
equivalent to

a=2.0
call mistaken(a=a,c=3.0)

In that calling sequence, the "a" on the left of the equals refers
to the dummy argument in the subroutine, and the "a" on the right
refers to the variable in the main program that was just assigned a
value of 2.0.

The other problems would still in the code (referencing the dummy
argument "b" when it is not present, etc.) even with this change.

$.02 -Ron Shepard

Richard Maine

unread,
Feb 1, 2008, 3:46:39 PM2/1/08
to
e p chandler <ep...@juno.com> wrote:

> Perhaps you want something like:
>
> if (.not. present(b)) b=1.23456

Um. No. That is guaranteed to be wrong. If b isn't present, then you
aren't allowed to define it. I would like to have a feature where a
non-present dummy could be used as a local variable not associated with
any actual argument. But the language doesn't have such a thing.

Gib Bogle

unread,
Feb 1, 2008, 3:56:46 PM2/1/08
to

Code that changes the value of a simple constant used to be a rite of
passage for Fortran programmers. Can modern compilers do this, e.g.
Intel Fortran?

Steve Lionel

unread,
Feb 1, 2008, 4:11:03 PM2/1/08
to
On Feb 1, 3:56 pm, Gib Bogle <bo...@ihug.too.much.spam.co.nz> wrote:

> Code that changes the value of a simple constant used to be a rite of
> passage for Fortran programmers. Can modern compilers do this, e.g.
> Intel Fortran?

Intel Fortran will give you a run-time error if you try to do this,
though some earlier versions did not. There is an option to pass a
writable copy of the constant instead (which is then discarded on
return).

Steve

James Giles

unread,
Feb 1, 2008, 4:25:39 PM2/1/08
to
Gib Bogle wrote:
...

>> The value of 2.0 might change, though.
>
> Code that changes the value of a simple constant used to be a rite of
> passage for Fortran programmers. Can modern compilers do this, e.g.
> Intel Fortran?


They probably shouldn't, but many probably do. I don't have a
copy of the Intel compiler, so I can't answer specifically.

You have two recourses. If you explicitly specify INTENT, then
the compiler is required to detect and report any actual argument
that's not definable if the corresponding dummy has OUT among
its intents. Unfortunately, compilers are not required to detect
or report violations of INTENT within the called procedure
(most do). The second possibility is to declare the dummy
argument with the VALUE attribute. This causes an anonymous
temporary to be created, the value of the actual argument is
copied into that temporary, the dummy argument is associated
with the copy, and the temporary is discarded when the procedure
terminates.

The problem with the above is that they both depend on the callee
to be declared a certain way. If not, the caller can still make the
mistake. I think that an undefinable actual argument should be
passed according to the rule for VALUE attributed args regardless
of the declared attributes of the dummy. I think that should be made
the official rule in the standard. It's backward compatible (no
conforming program can rely on it not happening). And it guarantees
the problem won't occur.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


James Van Buskirk

unread,
Feb 1, 2008, 4:41:05 PM2/1/08
to
"Steve Lionel" <steve....@intel.com> wrote in message
news:e378ace7-f9fe-42fc...@e23g2000prf.googlegroups.com...

C:\Program Files\Microsoft Visual Studio 8\James\clf\steve_is_right>type
steve_i
s_right.f90
program steve_is_right
implicit none
character(80) mess

mess = 'Steve is WRONG'
read(mess,10)
write(*,10)
10 format(14HSteve is right)
end program steve_is_right

C:\Program Files\Microsoft Visual Studio 8\James\clf\steve_is_right>ifort
steve_
is_right.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.

-out:steve_is_right.exe
-subsystem:console
steve_is_right.obj

C:\Program Files\Microsoft Visual Studio
8\James\clf\steve_is_right>steve_is_rig
ht
Steve is WRONG

C:\Program Files\Microsoft Visual Studio
8\James\clf\steve_is_right>c:\gfortran\
win64\bin\x86_64-pc-mingw32-gfortran steve_is_right.f90 -osteve_is_right

C:\Program Files\Microsoft Visual Studio
8\James\clf\steve_is_right>steve_is_rig
ht
At line 6 of file steve_is_right.f90
Fortran runtime error: Constant string in input format
(14HSteve is right)
^

Is the ifort result due to using an earlier version, or does the
current version have this behavior, which is normal for codes with
HOLLERITH and ENCODE/DECODE?

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Dick Hendrickson

unread,
Feb 1, 2008, 5:46:16 PM2/1/08
to
James Giles wrote:
> Gib Bogle wrote:
> ...
>>> The value of 2.0 might change, though.
>> Code that changes the value of a simple constant used to be a rite of
>> passage for Fortran programmers. Can modern compilers do this, e.g.
>> Intel Fortran?
>
>
> They probably shouldn't, but many probably do. I don't have a
> copy of the Intel compiler, so I can't answer specifically.
>
> You have two recourses. If you explicitly specify INTENT, then
> the compiler is required to detect and report any actual argument
> that's not definable if the corresponding dummy has OUT among
> its intents.

No, that's not right. Compilers aren't required to detect
errors across a CALL when INTENT is specified. INTENT isn't
one of the things listed in 12.3.1.1 that requires an explicit
interface. The only interesting constraint under INTENT
prohibits passing an INTENT(IN) pointer to an INTENT([IN]OUT)
pointer; that's because the pointerness requires an explicit
interface, so the check is free.

INTENT is really a local documentation aid. There's a constraint
that prohibits directly modifying an INTENT(IN) dummy, but
that's easily misused/abused by passing the INTENT arguments
on to a non-conforming procedure.

Dick Hendrickson

utab

unread,
Feb 1, 2008, 5:52:24 PM2/1/08
to
On Feb 1, 7:08 pm, nos...@see.signature (Richard Maine) wrote:

You are right that I should have been more clear. Thanks for the
clarifications so far.

Here are my humble questions:

1.) intent in(out) arguments should always be supplied but optional
arguments may be dropped from the call, however then the subsequent
arguments should be given with the keywords for the compiler to
distinguish them. This was sth. I missed. Thas was the 1st mistake. So
the right call should be like:

aa=1.0
call mistaken(aa,c=3.0)

as some of the gentle posters suggested.

2.) I was playing with this code actually to see what will change and
see some possible error conditions and learn from them. The actual
question was "find the error in the subroutine below"

subroutine mistaken(a,b,c)
real, intent(inout) ::a

real, intent(out), optional :: b
real, intent(in) :: c
a=2*c*b
if(present(b)) b=2*a
end subroutine mistaken

The whole given part of the code was the above, and after some
checking(I was on the train when I first checked this), if b is
dropped, the problem would be, I guess, is that optional argument is
undefined so that

a=2*c*b

is not defined. Is this the actual error. At least, I think in this
way.

Rgds

Richard Maine

unread,
Feb 1, 2008, 7:16:52 PM2/1/08
to
utab <umut....@gmail.com> wrote:

> 1.) intent in(out) arguments should always be supplied

That's not so. Intent is orthogonal to optionality. Having an optional
intent(inout) argument is fine.

> subroutine mistaken(a,b,c)
> real, intent(inout) ::a
> real, intent(out), optional :: b
> real, intent(in) :: c
> a=2*c*b
> if(present(b)) b=2*a
> end subroutine mistaken
>
> The whole given part of the code was the above, and after some
> checking(I was on the train when I first checked this), if b is
> dropped, the problem would be, I guess, is that optional argument is
> undefined so that
>
> a=2*c*b
>
> is not defined. Is this the actual error. At least, I think in this
> way.

Yes, this is an "error" in the subroutine (in addition to the errors
noted in calling it). To be quite pedantic, the subroutine isn't
technically necessarily erroneous. It is an error to call this
subroutine with b not present, for the reason you mention. But since it
is possible to include this subroutine in a valid program, the
subroutine is not technically invalid by itself. When you put it
together with a main program that calls it with b omitted, then that
combination is invalid.

One might consider it "silly" to have a subroutine where an argument is
declared optional, but can never be validly omitted. But the standard
doesn't prohibit such "silly" things; there are even times when they
make sense. Examples of simillarly "silly" things include

x = 1.0 !-- This value never gets used.
x = 2.0

and

if (.false.) then
...
end if

I have seen both constructs in real code and in contexts where there use
was at least somewhat sensible.

e p chandler

unread,
Feb 2, 2008, 10:57:31 AM2/2/08
to
On Feb 1, 3:46 pm, nos...@see.signature (Richard Maine) wrote:

> e p chandler <e...@juno.com> wrote:
>
> > Perhaps you want something like:
>
> > if (.not. present(b)) b=1.23456
>
> Um. No. That is guaranteed to be wrong. If b isn't present, then you
> aren't allowed to define it. I would like to have a feature where a
> non-present dummy could be used as a local variable not associated with
> any actual argument. But the language doesn't have such a thing.
>

Thanks for the correction - and for reading my mind! Had I not posted
in haste, I would have assigned either a set value or the value of b
(if present) to a local variable. :-(.

-- e

0 new messages