Discussion:
Is there a way in Fortran to designate an integer value as integer*8 ?
(too old to reply)
Lawrence D'Oliveiro
2024-10-27 21:01:40 UTC
Permalink
The "parameter adjustment" above is explicitly listed as undefined
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point
into, or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or
just beyond, the same array object”. So long as it *does* point
“into, or just beyond, the same array object”, it is fine.
What you are writing is equivalent to
You don’t understand what pointer arithmetic means, do you?
Hey, look! Somebody who doesn’t understand how pointer arithmetic works!
Lynn McGuire
2024-10-28 22:58:08 UTC
Permalink
Post by Lawrence D'Oliveiro
The "parameter adjustment" above is explicitly listed as undefined
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point
into, or just beyond, the same array object (6.5.6)."
Read it again: note the qualification “that does not point into, or
just beyond, the same array object”. So long as it *does* point
“into, or just beyond, the same array object”, it is fine.
What you are writing is equivalent to
You don’t understand what pointer arithmetic means, do you?
Hey, look! Somebody who doesn’t understand how pointer arithmetic works!
Are you 12 years old ?

Lynn
James Kuyper
2024-10-29 18:11:42 UTC
Permalink
Lawrence snipped the following extremely relevant text from his
response, which made it very unclear what the controversy was about.
#include "f2c.h"
/* Common Block Declarations */
struct {
integer array[10];
} _BLNK__;
#define _BLNK__1 _BLNK__
/* Subroutine */ int foo_(integer *i__, integer *n)
{
/* System generated locals */
integer i__1;
/* Local variables */
static integer k;
/* Parameter adjustments */
--i__;
/* Function Body */
i__1 = *n;
for (k = 1; k <= i__1; ++k) {
i__[k] = k + _BLNK__1.array[k - 1];
}
return 0;
} /* foo_ */
The common block handling looks OK, but the dummy argument
(aka parameters, in C parlance) handling is very probably not.
The "parameter adjustment" above is explicitly listed as undefined
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point
into, or just beyond, the same array object (6.5.6)."
[snipped ensuing conversation, which contained nothing of value.]

It would be more appropriate to cite 6.5.6 itself, rather than Annex J2,
which is just a summary. The summary often doesn't go into as much
detail as the clause being summarized, and the details that are left out
of the summary are occasionally relevant.
It would also be better to cite a newer version of the standard. The
latest I have is n3096, dated 2023-04-01 (but it's not an April Fool's
joke), and in that version 6.5.6p10 says:

"If the pointer operand and the result do not point to elements of the
same array object or one past the last element of the array object, the
behavior is undefined."

However, there was equivalent wording in all previous versions of the C
standard, so it doesn't really matter which version you look at.

As far as C is concerned, whether or not the adjustment had undefined
behavior depends entirely upon where i__ points when foo_() is called.
If it points at any location in an array other than the first element of
the array (including one past the end of the array), then --i__ is
perfectly legal, because the result will point at an earlier element of
the same array. For instance, this would be perfectly legal:

integer array[11]={0};
int ret = foo_(array + 1, 10);

I've seen code like this used to make C code look more like the Fortran
it was translated from, and in that context a function like this would
be called with a pointer to the first element of an array, in which case
the behavior is indeed undefined, which is why that's a bad way to
handle the translation. But it's the combination of foo_()'s definition,
and how it is called, that make the behavior undefined, not just the
code of foo_() itself.
Waldek Hebisch
2024-10-29 20:04:31 UTC
Permalink
Post by James Kuyper
Lawrence snipped the following extremely relevant text from his
response, which made it very unclear what the controversy was about.
#include "f2c.h"
/* Common Block Declarations */
struct {
integer array[10];
} _BLNK__;
#define _BLNK__1 _BLNK__
/* Subroutine */ int foo_(integer *i__, integer *n)
{
/* System generated locals */
integer i__1;
/* Local variables */
static integer k;
/* Parameter adjustments */
--i__;
/* Function Body */
i__1 = *n;
for (k = 1; k <= i__1; ++k) {
i__[k] = k + _BLNK__1.array[k - 1];
}
return 0;
} /* foo_ */
The common block handling looks OK, but the dummy argument
(aka parameters, in C parlance) handling is very probably not.
The "parameter adjustment" above is explicitly listed as undefined
"Addition or subtraction of a pointer into, or just beyond, an array
object and an integer type produces a result that does not point
into, or just beyond, the same array object (6.5.6)."
[snipped ensuing conversation, which contained nothing of value.]
It would be more appropriate to cite 6.5.6 itself, rather than Annex J2,
which is just a summary. The summary often doesn't go into as much
detail as the clause being summarized, and the details that are left out
of the summary are occasionally relevant.
It would also be better to cite a newer version of the standard. The
latest I have is n3096, dated 2023-04-01 (but it's not an April Fool's
"If the pointer operand and the result do not point to elements of the
same array object or one past the last element of the array object, the
behavior is undefined."
However, there was equivalent wording in all previous versions of the C
standard, so it doesn't really matter which version you look at.
As far as C is concerned, whether or not the adjustment had undefined
behavior depends entirely upon where i__ points when foo_() is called.
If it points at any location in an array other than the first element of
the array (including one past the end of the array), then --i__ is
perfectly legal, because the result will point at an earlier element of
integer array[11]={0};
int ret = foo_(array + 1, 10);
I've seen code like this used to make C code look more like the Fortran
it was translated from, and in that context a function like this would
be called with a pointer to the first element of an array, in which case
the behavior is indeed undefined, which is why that's a bad way to
handle the translation. But it's the combination of foo_()'s definition,
and how it is called, that make the behavior undefined, not just the
code of foo_() itself.
There is more context to this: AFAICS the relevant use case is
handling Fortran/f2c calling convention where on entry to the function
the pointer points to first element of Fortran array. This element
has index 1 in Fortran but would have index 0 in generated C code.
f2c wanted to use the same indices as in Fortran, so is doing "adjustment".
But the resulting base pointer points one element before array,
so in normal use 6.5.6 applies.

In effect, in this case Lawrence is making noise but the other
folks are correct.
--
Waldek Hebisch
Loading...