A doubly linked-list in C

P

paul.richard.thomas

(F>=90 also adds optional specification of INTENT IN/OUT/INOUT,
the first two of which *may* copy only one direction. F03 adds
optional explicit VALUE, and C 'interop' features that as one would
expect support the C method. Some compilers did (and do) have
extensions to specify by-ref/value and other calling conventions,
but always as extensions, and TTBOMLK always using either
(pseudo-)function syntax or comment(-like) syntax, not slashes.)

The VALUE attribute, introduced by fortran 2003, enables passibling by
value. Otherwise passing by reference is the norm.
The only thing I know of that is even reasonably close is that
PL/I normally passes by-reference, but specifies that extra
*parentheses* around an argument mean it is first copied to a
temporary (and not copied back) giving the effect of by-value.

Fortran does this too. For example:

$ cat dogs.f90
integer :: i = 42
call foo((i))
print *, i
call foo (i)
print *, i
call bar (i)
print *, i
contains
subroutine foo(i)
integer :: i
i = i + 1
end subroutine
subroutine bar(i)
integer, value :: i
i = i + 1
end subroutine
end

$ /irun/bin/gfortran -fdump-tree-original dogs.f90

$ ./a
42
43
43

$ cat dogs*nal
bar (integer(kind=4) i)
{
i = i + 1;


foo (integer(kind=4) & i)
{
*i = *i + 1;


MAIN__ ()
{
static integer(kind=4) i = 42;
static integer(kind=4) options.0[8] = {68, 255, 0, 0, 0, 1, 0, 1};
static void foo (integer(kind=4) &);
static void bar (integer(kind=4));

_gfortran_set_options (8, (void *) &options.0);
{
integer(kind=4) D.642;

D.642 = i;
foo (&D.642);
}
{
/* PRINT eliminated here */
}
foo (&i);
{
/* PRINT eliminated here */
}

bar (i);
{
/* PRINT eliminated here */
}
}


where the code for the PRINT statements has been cut for clarity.

Note the copy in for the first call to foo, using D.639 as temporary,
and the passing by reference of i in the second call. The passing by
value in BAR is evident both in the code for bar and its call.

Paul
 
D

Dik T. Winter

>
> Fortran does this too. For example:
>
> $ cat dogs.f90
> integer :: i =3D 42
> call foo((i))

Disallowed in Fortran 77 because foo changes its argument.
> print *, i
> call foo (i)

Disallowed in Fortran 77 because foo changes its argument.

Are both allowed in Fortran 90?
 
J

Jugoslav Dujic

Dik said:
Disallowed in Fortran 77 because foo changes its argument.

Correct. If the value of the dummy argument is changed,
the actual argument must be modifiable (a lvalue, in Cspeak).
This is a standards violation (not required to be detected
by compilers and probably even harmless, but still a violation).
Disallowed in Fortran 77 because foo changes its argument.

Huh??? Why would it be disallowed? I is a variable, therefore
modifiable. It wouldn't be allowed if I were a parameter
(const in C speak). You certainly may change argument values in
all flavors of Fortran (and quite a number of other languages).
Are both allowed in Fortran 90?

The relevant rules in this regard haven't been changed compared
with F77, AFAIK.
 
I

Ian Bush

...
 > > The only thing I know of that is even reasonably close is that
 > > PL/I normally passes by-reference, but specifies that extra
 > > *parentheses* around an argument mean it is first copied to a
 > > temporary (and not copied back) giving the effect of by-value.
 >
 > Fortran does this too.  For example:

Some implementations of Fortran may do. It is not required.
 >
 > $ cat dogs.f90
 >   integer :: i =3D 42
 >   call foo((i))

Disallowed in Fortran 77 because foo changes its argument.

Agreed

 >   print *, i
 >   call foo (i)

Disallowed in Fortran 77 because foo changes its argument.

But I can't see what the problem is here. Have you misread i as a
parameter ?
Are both allowed in Fortran 90?

The situation has not changed here as far as I know in any of the 3
post Fortran 77 standards, so the first is not allowed but I can't see
why you think the second is problematic,

Ian
 
J

Jugoslav Dujic

Ian said:
Some implementations of Fortran may do. It is not required.

Let's be careful about terminology here. The critical case is
argument aliasing. Let's consider the following case:

subroutine shiftarray(a,b,n)
integer,intent(out):: a(n)
integer,intent(in):: b(n)
a(1:n-1) = b(2:n)
a(n) = 0
end subroutine shiftarray

Now, if you do:

integer i(5) = (/1,2,3,4,5/)
call shiftarray(i,i,5)
write(*,*) i

you're violating the standard -- both A and B dummy arguments
are aliased to the same actual argument, therefore the routine must
not modify either of them (maybe my wording was loose here, but
you get the point). The end result is NOT guaranteed to be
(/2,3,4,5,0/) (and indeed, often isn't); the subroutine may
even "start WWIII".

However, if you do:

call shiftarray(i,(i),5)

The compiler is required to "do the right thing", and perform
copy-in *semantics* (if not implementation) for the second
argument.
 
R

robin

David Thompson said:
(e-mail address removed) wrote:
[ in a thread that mutated into whether C has pass-by-reference ]
No, Fortran passed everything (except arrays) by copy/restore. To pass
by reference, you had to decorate the formal paramter name with slashes:

SUBROUTINE SUB1(I, /J/) I passed by copy/restore, J by reference

Pass by copy/restore is similar to pass by value except that the final
value of the parameter is copied back into the argument when the
subroutine returns.

I think you must be remembering a dialect or even variant. I've never
seen syntax like that in any Fortran implementation, text, published
code, or standard back to 77. 66 was before I was playing close
attention, but the description of changes in 77 doesn't include any
such thing, and I can't imagine anything so fundamental going
unmentioned. Does the collective memory of c.l.f include this?

Since at least 77, Fortran's rules on 'argument association' have been
carefully written to allow either by-reference or copy-in-out at the
implementor's choice; a program which detects (or relies on) the
difference is nonstandard. F90 and later nearly specify (at least
very strongly hint at) certain cases involving new features, but
the normal 'ordinary data' cases remain implementor-choice.
It is true an implementor is more likely to choose copy for scalars
than arrays, at least actually or potentially large arrays, and
again F>=77 distinguishes between passing scalars and passing arrays
in ways that allow that choice, although without saying why.

(F>=90 also adds optional specification of INTENT IN/OUT/INOUT,
the first two of which *may* copy only one direction. F03 adds
optional explicit VALUE, and C 'interop' features that as one would
expect support the C method. Some compilers did (and do) have
extensions to specify by-ref/value and other calling conventions,
but always as extensions, and TTBOMLK always using either
(pseudo-)function syntax or comment(-like) syntax, not slashes.)

The only thing I know of that is even reasonably close is that
PL/I normally passes by-reference, but specifies that extra
*parentheses* around an argument mean it is first copied to a
temporary (and not copied back) giving the effect of by-value.

PL/I passes by address.
For constants and expressions, a temporary is always created,
and the address of the temporary is passed.
Also, when there is a mismatch of type between the
argument and parameter [dummy argument in Fortran terminology]
PL/I creates a temporary and performs the type conversion.
An argument that is a variable enclosed in parentheses
is a special case of an expression, for which a temporary is created.

The creation of the temporary for constant arguments
was designed to avoid the problem in Fortran of corrupting a constant.
 
R

robin

glen herrmannsfeldt said:
PL/I will also make a copy if the argument type is declared,
and different (enough).

PL/I creates a temporary whenever the type of argument
is different from the type of the parameter. PL/I then performs
a conversion to the appropriate type.
There is an exception, when the called procedure is external
and has not been declared in the calling procedure.
If, for example, you passed a fixed
point variable to a subroutine expecting floating point, and
properly declared it

It is not necessary to declare anything for the conversion
to be performed. It is done automatically, as described above.
 
R

Richard Maine

The VALUE attribute, introduced by fortran 2003, enables passibling by
value. Otherwise passing by reference is the norm.

While I assume you actually know this, I'll post anyway for people who
might otherwise read this thread and think that the above is literally
true.

Nowhere in any version of the Fortran standard is passing by reference
specified. Several provisions of the standard are there specifically to
allow compilers to choose different passing mechanisms. Furthermore,
there do exist plenty of cases - not just where the VALUE attribute is
specified - where compilers implement argument passing in ways other
than pass by reference. I don't feel like spending the effort to come up
with a list of such cases, particularly as I suspect you could do it
just as well as I could.

If you had said something like that passing by reference is the most
common implementation for most contexts, I'd have said nothing in reply.
Perhaps that's what you meant by "norm". But the word "norm" can be read
to have much more meaning than that, often being nearly a synonym with
"standard". Pass by reference is certainly not part of the standard.
Assuming pass byreference usually constitutes a programming error, and
one that is reasonably likely to cause bugs, particularly when
optimizers are involved.
 
G

glen herrmannsfeldt

PL/I creates a temporary whenever the type of argument
is different from the type of the parameter. PL/I then performs
a conversion to the appropriate type.
There is an exception, when the called procedure is external
and has not been declared in the calling procedure.

Does it if the underlying type is the same? Say on most
modern processors you pass a FLOAT BIN(35) to a FLOAT BINARY(36),
such that the internal form is the same?
It is not necessary to declare anything for the conversion
to be performed. It is done automatically, as described above.

If you don't declare it, how does it know the type in the
called routine?

-- glen
 
F

Franken Sense

In Dread Ink, the Grave Hand of glen herrmannsfeldt Did Inscribe:
If you don't declare it, how does it know the type in the
called routine?

I think this is a strong criticism from the point-of-view of strongly-typed
languages.

Meanwhile, it looks like I'm gonna dump it into a perl hash.

It's nice to read Glen in clc.
 
R

robin

glen herrmannsfeldt said:
In comp.lang.fortran robin said:
Does it if the underlying type is the same? Say on most
modern processors you pass a FLOAT BIN(35) to a FLOAT BINARY(36),
such that the internal form is the same?

The internal form is irrelevant.
Because the attributes are different,
PL/I creates a temporary.
If you don't declare it, how does it know the type in the
called routine?

From the attributes of the parameters in the called
procedure.
 
R

robin

Franken Sense said:
In Dread Ink, the Grave Hand of glen herrmannsfeldt Did Inscribe:


I think this is a strong criticism from the point-of-view of strongly-typed
languages.

??
Matching the types on procedure calls is an important
characteristic of any language, and in PL/I was designed to
eliminate a common class of error.

This type of error was prevalent in Fortran at the time
PL/I was introduced in 1966.
 
F

Franken Sense

In Dread Ink, the Grave Hand of robin Did Inscribe:
??
Matching the types on procedure calls is an important
characteristic of any language, and in PL/I was designed to
eliminate a common class of error.

This type of error was prevalent in Fortran at the time
PL/I was introduced in 1966.

I'd be curious to know if that were a reaction to fortran's standardization
in the same year.

I don't know if this is particularly relevant to C, but standard fortran
existed, I don't know, 15 years before standard C. Sometimes I think
people talk about The Standard like my mom talks about The Church, as if
there were only one. If there's only one, why is her's better, even as it
rejects every form of ecumenism?

Then there's perl:

#!/usr/bin/perl
# perl m21.pl
use strict;
use warnings;


local $/="";
my $len = 5;

while( my $line = <DATA> ) {
chomp($line);
my @s = split /\s+/, $line;
for my $i (0..$#s) {
$len = length($s[$i]);
print "s[$i] = $s[$i] $len \n";
}

}
__DATA__
44:005:017 Then the high priest rose up, and all they that were with him,
(which is the sect of the Sadducees,) and were filled with
indignation,

44:005:018 And laid their hands on the apostles, and put them in the
common prison.

44:005:019 But the angel of the Lord by night opened the prison doors,
and brought them forth, and said,

44:005:020 Go, stand and speak in the temple to the people all the words
of this life.

# abridged output
s[0] = 44:005:018 10
s[1] = And 3
s[2] = laid 4
s[3] = their 5
s[4] = hands 5
s[5] = on 2
s[6] = the 3
s[7] = apostles, 9
s[8] = and 3
s[9] = put 3
s[10] = them 4
s[11] = in 2
s[12] = the 3
s[13] = common 6
s[14] = prison. 7
s[0] = 44:005:019 10
s[1] = But 3
s[2] = the 3
s[3] = angel 5
s[4] = of 2
s[5] = the 3
s[6] = Lord 4
s[7] = by 2
s[8] = night 5
s[9] = opened 6
s[10] = the 3
s[11] = prison 6
s[12] = doors, 6
s[13] = and 3
s[14] = brought 7
s[15] = them 4
s[16] = forth, 6
s[17] = and 3
s[18] = said, 5

C:\MinGW\source>

Perl isn't strongly-typed and gets everything right on the nuts. Perl has
no standard.
--
Frank

[Newt Gingrich] is the most unpopular politician in America. His favorable
rating is only four points higher than the Unabomber.
~~ Al Franken, 1996
 
R

robin

Franken Sense said:
In Dread Ink, the Grave Hand of robin Did Inscribe:


I'd be curious to know if that were a reaction to fortran's standardization
in the same year.

I'd say that it had/has nothing to do with that event.

The language PL/I had been under development for a couple of years prior.

As well as taking some of the best features of those other languages,
PL/I was intended to overcome the deficiencies, of which
corrupting constants was one such. (Another one, incidentally,
was to avoid the problem of using the wrong edit descriptor
for a given type, in I/O statements.)
 
G

glen herrmannsfeldt

(snip regarding PL/I)

< I'd be curious to know if that were a reaction to fortran's
< standardization in the same year.

As I understand it, IBM has hoping to replace Fortran with PL/I.
That is, not supply Fortran compilers for OS/360, but instead
PL/I and a Fortran to PL/I converter. That obviously didn't happen.
Among the reasons are that the PL/I compiler took too long to
write (all in assembler) and ran too slow (for the machines at
the time).

In any case, the IBM Fortran IV compilers are pretty much
Fortran 66 with fewer extensions than much of the competition
(such as DEC).

< I don't know if this is particularly relevant to C, but standard
< fortran existed, I don't know, 15 years before standard C.

Until 1966, IBM was the standard for Fortran. ANSI C is 1989,
though K&R, which I believe was about 1976, could be considered
a de facto standard. 1989-1966=23, 1976-1954=22.

< Sometimes I think people talk about The Standard like my mom
< talks about The Church, as if there were only one.
< If there's only one, why is her's better, even as it rejects
< every form of ecumenism?

Fortran I, Fortran II, Fortran IV, Fortran 66, Fortran 77, ...

K&R C, C89, C99.

-- glen
 
F

Franken Sense

In Dread Ink, the Grave Hand of robin Did Inscribe:
I'd say that it had/has nothing to do with that event.

The language PL/I had been under development for a couple of years prior.

As well as taking some of the best features of those other languages,
PL/I was intended to overcome the deficiencies, of which
corrupting constants was one such. (Another one, incidentally,
was to avoid the problem of using the wrong edit descriptor
for a given type, in I/O statements.)

Did PL/I become standardized too? If so, how would you compare that
standard to either fortran's or C's?
--
Frank

A brief digression on whether that suspicious-looking mole is actually
cancer. ... Take this simple test called the ABC test. 'A' is for age. What
is your age? Is it over thirteen? If so, it's cancer. That's how the ABC
test works.
~~ Al Franken,
 
N

nmm1

As I understand it, IBM has hoping to replace Fortran with PL/I.
That is, not supply Fortran compilers for OS/360, but instead
PL/I and a Fortran to PL/I converter. That obviously didn't happen.

That's what they said, repeatedly. The relevant period was from
about 1965 to about 1975, after which they gave up. Again, with
Fortran 77, they implemented a joke system because they assumed
that nobody would use it. But that's another story ....


Regards,
Nick Maclaren.
 
R

Richard Tobin

glen herrmannsfeldt said:
As I understand it, IBM has hoping to replace Fortran with PL/I.
That is, not supply Fortran compilers for OS/360, but instead
PL/I and a Fortran to PL/I converter.

The PL/I "checkout compiler" was capable of "correcting" simple
Fortran programs into PL/I programs. For example, it would insert
semicolons at the end of lines, and insert declarations based on
the first letter of variable names.

-- Richard
 
G

glen herrmannsfeldt

< The PL/I "checkout compiler" was capable of "correcting" simple
< Fortran programs into PL/I programs. For example, it would insert
< semicolons at the end of lines, and insert declarations based on
< the first letter of variable names.

PL/I (F) had many "correction" warnings, including the missing
semicolon. PL/I also has the traditional Fortran implicit
typing based on the first letter.

Since this is also posted to comp.lang.c, I believe that early
C would implicitly declare variables as int. ANSI C requires
some declaration, but if the type isn't included it will
assume int.

auto i;

will delcare in int variable i, with the otherwise useless
auto declaration.

-- glen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top