reference type for C

J

James Kuyper

So, you can say:

x = pointer + (pointer - pointer);

or

x = pointer - pointer + pointer;

but not:

x= pointer + pointer - pointer;

True, but not relevant as a response to Keith's comment, because your
examples did not include any unary + operators. The constraint that
Keith refers to is violated by the following example:

x = +pointer;
 
J

James Kuyper

So, you can say:

x = pointer + (pointer - pointer);

or

x = pointer - pointer + pointer;

but not:

x= pointer + pointer - pointer;

True, but not relevant as a response to Keith's comment, because your
examples did not include any unary + operators. The constraint that
Keith refers to is violated by the following example:

x = +pointer;
 
J

James Kuyper

On 05/19/2013 05:38 PM, Keith Thompson wrote:
....
There is no unary "+" operator for pointers. The operand of unary "+"
or "-" must be of arithmetic type; this is a constraint.

I'm not sure I've ever deliberately used the unary + operator, so it's
not surprising that I've forgotten what the constraints are - but I
should have checked before posting.
 
J

James Kuyper

Counting one is where you take a number, let's say 42, and
ask the subject what is the nest number.

So, counting on "from x" (is that the proper way to use the phrase?)
means x+1? Your definition uses "nest" (I presume, "next"?) at a key
point. Is the distinction you're making the one between x+6 and
x+1+1+1+1+1+1? They're equivalent, but if you only know how to do the
latter, I suppose it could be said that you don't know how to do
arithmetic, though that's not how I'd describe the situation.
It's a necessary ability for numeracy, but it isn't in itself
considered enough to establish numeracy. It's a semantic argument,
of course.
Array notation is counting on for pointers. ...

OK - so that means I was wrong. pointer[6] is not defined in terms of
repeatedly adding 1 to pointer 6 times. If p points at the mth element
of a array, p[n] is defined as pointing at the (m+n)th element of the
array (so long as the array contains at least m+n elements). Therefore,
if pointer[6] is just "counting on", and therefore not an example of
"pointer arithmetic", then you seem to be saying that m+n is not an
example of arithmetic - at which point I reach total confusion as to the
distinction you're making.
... So it's not pointer
arithmetic. Again, it's a semantic argument. But it's not
unreasonable. Knowing that number 42 is a reasonable but
not excessive distance down the street doesn't equate to
knowing that 42 = 6 times 7.

The standard does not define any meaning for multiplication that applies
to pointer arguments. If neither addition, nor (presumably?) subtraction
count as pointer arithmetic, and neither multiplication nor division are
even defined in this context, what is the motivation for using the word
"arithmetic" as part of this phrase? I'd recommend a different term that
doesn't give the false appearance of having some connection to the term
"arithmetic" as it applies to numbers.
 
K

Keith Thompson

Ian Collins said:
One of the other significant differences between the two is with an
expression like

const size_t n = 42;
int i[n];

In C, i is a VLA, in C++ it is a normal array.

Yes, but are there cases where it matters, i.e., where a given
program has different semantics in C and C++ because of it?
There are contexts where VLAs aren't allowed, but that just means
that some program are valid C++ and invalid C.
 
K

Keith Thompson

ralph said:
I suppose [] isn't an arithmetic operator.

This thread is tough because we are mixing in what might be going on
and what did go on back then. In the "legacy" days the array operator
was nothing but an arithmentic operator.

Mr Kuyper pointed out that the 'modern' C standard defines array to
*behave* as *(array+i), the fact is back then, array *was*
*(array+i). The array operator was merely short-hand. Underneath,
after the preprocessor, array became *(array + i ) which is
definitely 'arithmetic'. <g>

This was easily demonstrated as both the following would compile and
produce the same result...

x = array;
or
x = i[array];

The latter statement varied depending on vendor and warning levels.
eg, some would allow
x = 5[array]; // a constant, but not
x = i[array];

While the 'replacement' represented no real impact in most cases,
there was still a lot of mythology surrounding the 'array operator',
thus those of us programming in late 90s and 80s tended to avoid array
notation like the plague, unless clarity was required (or requested).
<bg>


What do you think has changed since the "legacy days"?

The [] operator is still commutative; array is still equivalent
to i[array], even in C11. The mapping of x[y] to *(x+y) is not
done by the preprocessor, and as far as I know it never has been.

I'd be surprised to see a C compiler, even an old one, that doesn't
accept

x = i[array];

Which isn't to say that there was no such compiler, just that I'd
be surprised to see it. A compiler that conforms to any of C90,
C99, or C11 *must* accept 'x = i[array];" (though it's free to warn
about the programmer's lack of taste).
 
K

Keith Thompson

Malcolm McLean said:
Counting one is where you take a number, let's say 42, and

"Counting on"?
ask the subject what is the nest number.

"next number"?
It's a necessary ability for numeracy, but it isn't in itself
considered enough to establish numeracy. It's a semantic argument,
of course.
Array notation is counting on for pointers. So it's not pointer
arithmetic. Again, it's a semantic argument. But it's not
unreasonable. Knowing that number 42 is a reasonable but
not excessive distance down the street doesn't equate to
knowing that 42 = 6 times 7.

I wouldn't ordinarily complain about typos, but when you're using
English words and phrases in a way that seems quite distinct from
the way I believe most people use them, I suggest it's important
to be precise.

In a previous post, you seemed to be saying that pointer+integer
is "pointer arithmetic", but "pointer++" is not? If so, this
distinction is not supported by the C standard, which defines "++"
in terms of adding the value 1.

But now you seem to have some other reason for asserting that the []
operator does not involve "pointer arithmetic". Certainly arr
can be thought of as accessing the i'th element of array, and you
don't necessarily have to understand pointer arithmetic to use the
[] operator. But, as I'm sure you know, [] is defined in terms of
pointer+integer arithmetic.

I don't know just what distinction you're making. Whatever it is,
I don't believe it's meaningful.
 
E

Eric Sosman

I suppose [] isn't an arithmetic operator.

This thread is tough because we are mixing in what might be going on
and what did go on back then. In the "legacy" days the array operator
was nothing but an arithmentic operator.

Mr Kuyper pointed out that the 'modern' C standard defines array to
*behave* as *(array+i), the fact is back then, array *was*
*(array+i). The array operator was merely short-hand. Underneath,
after the preprocessor, array became *(array + i ) which is
definitely 'arithmetic'. <g>


You have it backwards. K&R says in 1978 that the subscript
operator "is interpreted in such a way that E1[E2] is identical
to *((E1)+(E2))." The original ANSI C Standard of 1989 says
"The *definition* [emphasis mine] ... is that E1[E2] is identical
to (*(E1+(E2)))." (Note the rather odd change in punctuation.)

That is, "behave as if identical" is original and "defined
as" is modern, not the other way around.
[...] those of us programming in late 90s and 80s tended to avoid array
notation like the plague, unless clarity was required (or requested).

Speak for yourself, not for "those of us." I wrote C in
the 2010's, 2000's, 1990's, 1980's, and 1970's, and in none of
those decades did I feel any impulse to avoid [].
 
G

glen herrmannsfeldt

(snip)
Mr Kuyper pointed out that the 'modern' C standard defines array to
*behave* as *(array+i), the fact is back then, array *was*
*(array+i). The array operator was merely short-hand. Underneath,
after the preprocessor, array became *(array + i ) which is
definitely 'arithmetic'. <g>
This was easily demonstrated as both the following would compile and
produce the same result...
x = array;
or
x = i[array];

(snip)

What do you think has changed since the "legacy days"?


Processors have different addressing modes.
The [] operator is still commutative; array is still equivalent
to i[array], even in C11. The mapping of x[y] to *(x+y) is not
done by the preprocessor, and as far as I know it never has been.

I'd be surprised to see a C compiler, even an old one, that doesn't
accept
x = i[array];
Which isn't to say that there was no such compiler, just that I'd
be surprised to see it.

I believe one of the DEC compilers about 20 years ago wouldn't do it,
but I don't remember what it did with it.

As well as I remember, that was the VAX/VMS days. I haven't tried it
on any VMS systems since then.

-- glen
 
G

glen herrmannsfeldt

(snip)
[...] those of us programming in late 90s and 80s tended to avoid array
notation like the plague, unless clarity was required (or requested).

Seems like 90's was a little late, but earlier, yes.
Speak for yourself, not for "those of us." I wrote C in
the 2010's, 2000's, 1990's, 1980's, and 1970's, and in none of
those decades did I feel any impulse to avoid [].

How do you write the loop inside strcpy() is you happen to
be writing one in C?

-- glen
 
M

Malcolm McLean

"Counting on"?

I don't know just what distinction you're making. Whatever it
is,I don't believe it's meaningful.
Let's say I ask a primary school child to count out 42
beans, and he does it correctly. This is not sufficient to
be called "arithmetic". It's knowing the numbers, or "counting on".
It's also "counting on" if we don't start from one, lets say we
have a pile of beans, which we tell him contains a hundred, and
ask him to unite another pile of 42 beans to it, and he takes
beans from the 42 pile one by one and goes "a hundred and one,
and hundred and two ..."
That's not enough to be able to say that the child can do
simple arithmetic.

But let's say I ask him to count out forty two beans, count
out five, and then unite the piles and count them. This is
arithemetic. Because he's now taking two numbers, manipulating
them to produce a third, and storing the result.

array[42] is counting on. ptr = array + 42 is arithmetic.
 
B

Bart van Ingen Schenau

On 05/19/2013 05:35 AM, Bart van Ingen Schenau wrote: ...

There's a few others.

Yes, your response reminded me of the difference in rules for name lookup
in the tag namespace and for nested types.
You're probably right about that.


I've posted versions of the following material three times, most
recently in a message dated 2011-06-19. It has never provoked much
discussion, which disappointed me.

What kind of discussion were you expecting?

You can compile and link both modules as C code, or as C++ code; the
resulting executables are guaranteed by the applicable standards to exit
with an failure status, for two entirely different sets of reasons,
depending upon which language is used (note that many compilers
automatically infer the language to be used from the extension on the
filename - you might need to rename the files to get them to actually
compile in one language rather than the other).

If you compile the first module with C, and the second with C++, it is
guaranteed to return a successful exit status. If C++ were really just
an extension to C, then what I've said about how this program's behavior
varies with the programming language would be impossible.

Actually, I believe you are wrong about the exit status of the various
possibilities. When both modules are compiled in the same language, then
the exit status of the application is guaranteed to be *success*.
It only results in a failure exit status if the first module is compiled
in C and the second in C++.

<snip>

Bart v Ingen Schenau
 
J

James Kuyper

On 05/20/2013 04:36 AM, Malcolm McLean wrote:
....
Let's say I ask a primary school child to count out 42
beans, and he does it correctly. This is not sufficient to
be called "arithmetic". It's knowing the numbers, or "counting on".
It's also "counting on" if we don't start from one, lets say we
have a pile of beans, which we tell him contains a hundred, and
ask him to unite another pile of 42 beans to it, and he takes
beans from the 42 pile one by one and goes "a hundred and one,
and hundred and two ..."
That's not enough to be able to say that the child can do
simple arithmetic.

But let's say I ask him to count out forty two beans, count
out five, and then unite the piles and count them. This is
arithemetic. Because he's now taking two numbers, manipulating
them to produce a third, and storing the result.

array[42] is counting on. ...

I don't see the connection between your example of counting out 42
beans, and array[42]. The defined behavior of array[42] does not involve
successively stepping through the first 42 positions in the array; it's
defined in terms of pointer addition, which in turn is defined in terms
of integer addition as applied to positions within an array, something
I'd consider to unambiguously be "arithmetic".
... ptr = array + 42 is arithmetic.

The defined behavior of array[42] is *(array + 42), so fundamentally,
the only difference between those two expressions is the difference
between "*(expression)" and "ptr = expression". I would call the first
"dereferencing" and the second "assignment". Your use of "counting on"
vs "arithmetic" to describe that distinction seems quite odd to me.
 
M

Malcolm McLean

On 05/20/2013 04:36 AM, Malcolm McLean wrote:
I don't see the connection between your example of counting out
42 beans, and array[42]. The defined behavior of array[42] does
not involve successively stepping through the first 42 positions > in the array; it's defined in terms of pointer addition, which in
turn is defined in terms of integer addition as applied to
positions within an array, something I'd consider to
unambiguously be "arithmetic".
Internally, yes, the processor will calculate 0x1234 + 42 to
give an address. But the programmer doesn't see that. He just
sees "take array and go 42 positions to the right". Like
going to a street called array avenue and finding house 42.
That's counting on.
(Then normally you step through an array, you seldom see
array[42] = x in real code, it's almost always
for(i=0;i<42;i++)
array = x.
Very clearly this is counting on.)
 
J

James Kuyper

What kind of discussion were you expecting?

Well, I was hoping to have the person who was describing C++ as a strict
superset of C to comment on how his position had changed as a result of
reviewing that program, or to explain why his position had not changed.
You didn't make exactly that claim, but you came close, and the three
previous occasions involved claims more explicitly of that type.

I was anticipating that someone might ask for an explanation - the
differences in the relevant rules are a bit obscure, and the code is not
annotated to explain why it makes a difference which language you use to
compile it.

However, at a minimum, I was hoping to have someone check it out and
tell me if I had made any errors, such as the following:

....
Actually, I believe you are wrong about the exit status of the various
possibilities. When both modules are compiled in the same language, then
the exit status of the application is guaranteed to be *success*.
It only results in a failure exit status if the first module is compiled
in C and the second in C++.

Thanks, I hope I'll remember to correct that discrepancy if I ever
decide to post that code again. Of course, the fact that the exit status
depends upon which language is used to compile the code is all that
matters for the point that I was making.
 
J

James Kuyper

On 05/20/2013 04:36 AM, Malcolm McLean wrote:
I don't see the connection between your example of counting out
42 beans, and array[42]. The defined behavior of array[42] does
not involve successively stepping through the first 42 positions > in the array; it's defined in terms of pointer addition, which in
turn is defined in terms of integer addition as applied to
positions within an array, something I'd consider to
unambiguously be "arithmetic".
Internally, yes, the processor will calculate 0x1234 + 42 to
give an address. But the programmer doesn't see that. ...

That depends upon how good the programmer's "eyes" are. Many C
constructs have behavior that can be defined as convenient packages of
more fundamental constructs; for instance, #ifdef can be defined in
terms of #if and defined(), while() can be defined in terms of if() and
goto, i++ can be defined in terms of + and =, and [] can be defined in
terms of * and +. I've always considered these packages as equivalent to
their component parts, and have never thought of them as unanalyzed
entities in their own right. YMMV
... He just
sees "take array and go 42 positions to the right". Like
going to a street called array avenue and finding house 42.

I can't say that I've ever thought about array subscripting in that way.
That's counting on.

I could, with equal justification, describe pointer+42 as "take the
position pointed at and go 42 positions to the right". For that matter,
I could equally well describe 3+42 as "Find 3 on the number line, and go
42 numbers to the right". That is, incidentally, precisely the way I was
taught to understand addition, several decades ago. I was also taught
techniques for manipulating symbols to implement addition, but that
description is precisely how I was taught what addition means. It also
corresponds pretty accurately to the way mathematicians formally derive
the concept of addition from the concept of the successor of a number.
If being able to describe array[42] that way justified describing it as
just "counting on", and not "arithmetic", then the same would also be
true of 3+42.
(Then normally you step through an array, you seldom see
array[42] = x in real code, it's almost always
for(i=0;i<42;i++)
array = x.
Very clearly this is counting on.)


I can see i++ as an example of counting on, but not array, which,
being defined as *(array+i), is pointer arithmetic as I understand the
term. If you'd re-written it as:

int *end = array + n;

for(int *p = array; p<end; p++)
*p = x;

then I could see the loop as an example of the distinction you're making
between "counting on" and "arithmetic". Of course, the preceding array+n
calculation is clearly pointer arithmetic.
 
E

Eric Sosman

(snip)
[...] those of us programming in late 90s and 80s tended to avoid array
notation like the plague, unless clarity was required (or requested).

Seems like 90's was a little late, but earlier, yes.
Speak for yourself, not for "those of us." I wrote C in
the 2010's, 2000's, 1990's, 1980's, and 1970's, and in none of
those decades did I feel any impulse to avoid [].

How do you write the loop inside strcpy() is you happen to
be writing one in C?

s/is/if/ ?

I'd do it in the time-honored way, with a pair of pointers.
That's not "avoiding [] like the plague," it's just using whatever
notation suits the use case better. How do *you*, might I ask,
write Gauss-Jordan elimination for a linear system?
 
K

Keith Thompson

glen herrmannsfeldt said:
Keith Thompson said:
Mr Kuyper pointed out that the 'modern' C standard defines array to
*behave* as *(array+i), the fact is back then, array *was*
*(array+i). The array operator was merely short-hand. Underneath,
after the preprocessor, array became *(array + i ) which is
definitely 'arithmetic'. <g>
This was easily demonstrated as both the following would compile and
produce the same result...
x = array;
or
x = i[array];

(snip)

What do you think has changed since the "legacy days"?


Processors have different addressing modes.


I don't see how that would necessarily affect the semantics of the []
operator, and it doesn't seem to be what ralph was referring to.

[snip]
 
G

glen herrmannsfeldt

(snip, someone wrote)
[...] those of us programming in late 90s and 80s tended
to avoid array notation like the plague, unless clarity
was required (or requested).
Seems like 90's was a little late, but earlier, yes.
Speak for yourself, not for "those of us." I wrote C in
the 2010's, 2000's, 1990's, 1980's, and 1970's, and in none of
those decades did I feel any impulse to avoid [].
How do you write the loop inside strcpy() is you happen to
be writing one in C?
s/is/if/ ?
Yes.

I'd do it in the time-honored way, with a pair of pointers.

I probably would too, though that is a slightly special case,
there the original value of the pointers isn't needed later.

Given the choice between copying the pointers and indexing,
I might go to indexing.
That's not "avoiding [] like the plague," it's just using whatever
notation suits the use case better.
How do *you*, might I ask, write Gauss-Jordan elimination
for a linear system?

Probably in Fortran. Well, there are plenty of them already
written in Fortran.

Not so long ago, I needed one in Java. I found one on the web,
according to the comments translated from a version in Fortran
originally for the IBM 650. (A vacuum tube decimal machine, with,
if I remember right, addressing in decimal.)

The tradtional way to write much of the matrix processing work
in Fortran is to consider the matrix as a 1D array, and compute
the appropriate offset. (This is still part of the newest
Fortran 2008 standard, part of assumed size arrays.)

The usual way to do matrix inversion, and I believe also
LU-decomposition, is to do it in place, remembering which
matrix elements are the input values, and which are the output
values.

There is the additional complication that one might want to
dimension an array larger than the size needed, but only use
part of it, such that the actual matrix elements aren't stored
contiguously. That was usual in the Fortran days before dynamic
allocation, and still useful even with dynamic allocation.

-- glen
 
M

Malcolm McLean

On 05/20/2013 07:32 AM, Malcolm McLean wrote:

I could, with equal justification, describe pointer+42 as "take the
position pointed at and go 42 positions to the right". For that matter,
I could equally well describe 3+42 as "Find 3 on the number line, and go
42 numbers to the right". That is, incidentally, precisely the way I was
taught to understand addition, several decades ago. I was also taught
techniques for manipulating symbols to implement addition, but that
description is precisely how I was taught what addition means.
Exactly. "Counting on" is how people who haven't been to school add numbers.
It's a semantic argument whether you call it "arithmetic" or not, but generally
it's not considered to be so. It's the step before arithmetic.
So at primary school, they work with the intuitive method first. It's a new
pedagogical theory - I wasn't taught with number lines, but first with
counters then to do it algorithmically.
 

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

Members online

Forum statistics

Threads
474,078
Messages
2,570,572
Members
47,204
Latest member
MalorieSte

Latest Threads

Top