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

Beginner Question – passing strings to subroutines

694 views
Skip to first unread message

marktyers

unread,
Aug 25, 2010, 2:30:12 AM8/25/10
to
Another noob question.
I want to be able to pass a fixed string to a subroutine but I can't
find any examples on the web and my attempt fails to compile. The
program currently looks like this:

c--
c This program contains the following examples:
c - a simple function that gets user input and returns it.
c - a subroutine that prints out the string supplied as a parameter
c--
program functions
character name*20, get_string*20
name = get_string()
call print_string(name)
end program functions

character*20 function get_string()
character name*20
write (*,'(a)',advance='no') 'Enter your name: '
read *,name
get_string = name
end

subroutine print_string(character name*20)
print *,name
end

When I try to compile I get the error:
-----------------------------------------------------------------------------
functions.for:19.44:

subroutine print_string(character
name*20)
1
Error: Unexpected junk in formal argument list at (1)
functions.for:6.72:

program
functions

1
functions.for:20.72:

print
*,name

2
Error: Two main PROGRAMs at (1) and (2)
-----------------------------------------------------------------------------
Can anyone help?

Richard Maine

unread,
Aug 25, 2010, 3:15:40 AM8/25/10
to
marktyers <mark...@gmail.com> wrote:

> subroutine print_string(character name*20)
...


> subroutine print_string(character
> name*20)
> 1
> Error: Unexpected junk in formal argument list at (1)

I think I detect someone who has seen some other programming languages
before. There are languages in which you declare the attributes of dummy
arguments right in whatever is equivalent to the subroutine statement,
but Fortran isn't one of them.

The subroutine statement has only the list of dummy argument names - not
their types. Something like

subroutine print_string(name)

Then declare the type an any other attributes of the dummy arguments in
separate statements, such as

character name*20

But while I'm on the subject, one other piece of advice. (I'll not
repeat my former ones). You should almost never declare dummy character
arguments with fixed lengths. It pretty much never achieves anything
useful and often causes bugs. Dummy character arguments should usually
be declared with assumed length as in

character name*(*)

This means that the length will be picked up from the actual argument.

If you declare a dummy argument with a length of 20, then the actual
argument must have length exactly 20. If it doesn't, then your program
is illegal in a way that compilers are not requires to detect. All kinds
of strange behaviors can result.

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

Les Neilson

unread,
Aug 25, 2010, 3:52:36 AM8/25/10
to

"marktyers" <mark...@gmail.com> wrote in message
news:f453e290-0582-4047...@a36g2000yqc.googlegroups.com...
> Another noob question.

> subroutine print_string(character name*20)
> print *,name
> end
>

subroutine print_string(name)
character(20) :: name
print *,name
end

Les

marktyers

unread,
Aug 25, 2010, 4:15:08 AM8/25/10
to
On Aug 25, 8:52 am, "Les Neilson" <l.neil...@nospam.co.uk> wrote:
> "marktyers" <markty...@gmail.com> wrote in message

That looks like it answers my question - can't test it until I get
home later though.

Many thanks Richard, Les

robin

unread,
Aug 25, 2010, 5:51:39 AM8/25/10
to
"marktyers" <mark...@gmail.com> wrote in message
news:f453e290-0582-4047...@a36g2000yqc.googlegroups.com...

| Another noob question.
| I want to be able to pass a fixed string to a subroutine but I can't
| find any examples on the web and my attempt fails to compile. The
| program currently looks like this:
|
| c--
| c This program contains the following examples:
| c - a simple function that gets user input and returns it.
| c - a subroutine that prints out the string supplied as a parameter
| c--
| program functions
| character name*20, get_string*20
| name = get_string()
| call print_string(name)
| end program functions
|
| character*20 function get_string()
| character name*20
| write (*,'(a)',advance='no') 'Enter your name: '
| read *,name
| get_string = name
| end
|
| subroutine print_string(character name*20)

Only "name" goes within the parentheses.
On a separate line, you declare name:
character*(len=*) :: name

| print *,name
| end


Ron Shepard

unread,
Aug 25, 2010, 11:39:01 AM8/25/10
to
In article <1jnr6xt.1wdck7r1967elqN%nos...@see.signature>,
nos...@see.signature (Richard Maine) wrote:

> If you declare a dummy argument with a length of 20, then the actual
> argument must have length exactly 20.

Is this right? I thought the actual argument had to have length of
*at least* 20.

Also, isn't it legal for the actual argument to be an array of
smaller strings, so long as the total array length is at least 20.
For example if the actual argument is declared as "character(len=4)
carray(5)" or as "character(len=1) carray(20)", aren't those also
legal actual arguments?

Maybe I'm confusing the storage association that is defined for
common blocks with those for dummy arguments, or something, but I
thought the above exceptions were legal.

$.02 -Ron Shepard

Richard Maine

unread,
Aug 25, 2010, 1:26:39 PM8/25/10
to
Ron Shepard <ron-s...@NOSPAM.comcast.net> wrote:

> In article <1jnr6xt.1wdck7r1967elqN%nos...@see.signature>,
> nos...@see.signature (Richard Maine) wrote:
>
> > If you declare a dummy argument with a length of 20, then the actual
> > argument must have length exactly 20.
>
> Is this right? I thought the actual argument had to have length of
> *at least* 20.

Yes, you are right. It occurred to me after I posted that I hadn't said
it quite right. Sequence association has lots of gotchas.

However, it still falls under the "all kinds of strange behaviors"
description that I gave. That case just happens to be a "strange
behavior" that is legal and is specified by the standard instead of one
that is illegal and compiler-dependent. For example, if you have an
actual argument of length longer than 20 and you assign a string to the
dummy argument, some people might expect that to be a lot like assigning
the string to the actual argument. It isn't. It just assignes to teh
forst 20 characters of the actual argument and leaves the rest with
whatever junk (or undefined status) it happened to have before.

An actual argument that is too small is a different matter and is
reasonably likely to result in overwriting memory of other variables.

dpb

unread,
Aug 25, 2010, 1:35:28 PM8/25/10
to
Richard Maine wrote:
...

> An actual argument that is too small is a different matter and is
> reasonably likely to result in overwriting memory of other variables.

Which is, of course, another reason for the OP to consider modules or
internal procedures as suggested in the earlier thread because then the
compiler will catch many of those mismatches (any that aren't runtime
only, anyway) owing to the explicit interface thereby generated.

--


nm...@cam.ac.uk

unread,
Aug 25, 2010, 1:59:05 PM8/25/10
to
In article <1jnrzbt.1fkb0h3aw2ydqN%nos...@see.signature>,
Richard Maine <nos...@see.signature> wrote:

>Ron Shepard <ron-s...@NOSPAM.comcast.net> wrote:
>
>> > If you declare a dummy argument with a length of 20, then the actual
>> > argument must have length exactly 20.
>>
>> Is this right? I thought the actual argument had to have length of
>> *at least* 20.
>
>Yes, you are right. It occurred to me after I posted that I hadn't said
>it quite right. Sequence association has lots of gotchas.
>
>However, it still falls under the "all kinds of strange behaviors"
>description that I gave. That case just happens to be a "strange
>behavior" that is legal and is specified by the standard instead of one
>that is illegal and compiler-dependent. ...

Yes. Sequence association is another of the features of Fortran that
I regard as an ancient mistake. This is not a condemnation, as I
doubt that anyone realised that it was a mistake (and why) until many
years later. And it's too deeply embedded to remove without major
incompatibilities.

In the special case of characters, that isn't true, and it was fairly
clearly a mistake, certainly by 1975. But I doubt that a better
specification would have been acceptable to either X3J3 or the wider
Fortran community at the time - Fortran 77 was regarded as radical
enough!


Regards,
Nick Maclaren.

Richard Maine

unread,
Aug 25, 2010, 2:34:36 PM8/25/10
to
robin <rob...@dodo.com.au> wrote:

> character*(len=*) :: name

There are several valid forms of the declaration syntax, but this isn't
one of them.

algol:~/temp> nagfor clf.f90
NAG Fortran Compiler Release 5.2(711)
Error: clf.f90, line 2: Syntax error
detected at LEN@=
***Malformed statement

or

lgol:~/temp> g95 clf.f90
In file clf.f90:2

character*(len=*) :: name
1
Error: Syntax error in character length specification at (1)

See other postings in the thread for some of the valid forms.

robin

unread,
Aug 25, 2010, 10:54:56 PM8/25/10
to
"Richard Maine" <nos...@see.signature> wrote in message news:1jns2nf.12esabbeshsweN%nos...@see.signature...

| robin <rob...@dodo.com.au> wrote:
|
| > character*(len=*) :: name
|
| There are several valid forms of the declaration syntax, but this isn't
| one of them.

You're right.
I mixed up the old and new forms.

Either character*(*) name
or
character (len=*) :: name


dpb

unread,
Aug 25, 2010, 11:35:05 PM8/25/10
to
robin wrote:
...

> Either character*(*) name
> or
> character (len=*) :: name

The form CHARACTER*(*) is an obsolescent feature in F95+

--

robin

unread,
Aug 26, 2010, 8:36:11 AM8/26/10
to
"dpb" <no...@non.net> wrote in message news:i53kfn$hip$1...@news.eternal-september.org...

It's almost always important for interfaces to be provided in new programs.
(Exceptions are old F77 forms where mismatches were exploited.)


robin

unread,
Aug 26, 2010, 8:23:16 PM8/26/10
to
"dpb" <no...@non.net> wrote in message news:i54njv$cbv$1...@news.eternal-september.org...
| robin wrote:

|> I mixed up the old and new forms.
|

| > Either character*(*) name
| > or
| > character (len=*) :: name
|
| The form CHARACTER*(*) is an obsolescent feature in F95+

I already said that these are the old and new forms.


dpb

unread,
Aug 26, 2010, 9:50:06 PM8/26/10
to

Yes, but the message to which I replied certainly implies "either" is as
good as t'other--I reinforced that the former was made obsolescent by
F95 for the (undoubtedly long gone) OP.

--

0 new messages