why use -> (not .) with pointers?

C

Clark S. Cox III

An alternative would be to not do silent type conversion in expressions --
except perhaps (for convenience) for some forms involving constants.

If there is no operator for int + float then the programmer would
have to put in explicit type casts as necessary, thus forcing the
programmer to pay attention at each substep to the types.


Such a scheme might do interesting things to expressions such as
toupper(HexChar) - 'A' + 10
due to the signed-ness ambiguity of char...

Except that there are no char's in that expression, only three int's. ;)
 
A

Alan Balmer

It's a convenience, because of the relative operator precedence.
It is easier and clearer to write:

structxp->fieldf
than
(*structxp).fieldf

I think the OP was proposing that you could write
structxp.fieldf
even when structxp was a pointer to a struct. It's true that the
compiler knows whether the dereference is required, but imo it doesn't
fit with C philosophy (and don't ask me to define that ;-)
 
A

Alan Balmer

So would you favour having different operators for integer and
floating-point addition?

Actually, in light of a problem I tracked down yesterday, that might
not be a bad idea :)

The end result was truncating fractional hours on a time report. Of
course, that wasn't all - the programmer had cast the result to a
float, then done an sprintf with %f. It got a segmentation violation
only sometimes.
 
P

P.J. Plauger

Note that the "->" operator works on *any* value, not just pointers.

Well, not *any* value. Early C was quick to convert an integer to
a pointer, which is what is required here. I'm not sure it tolerated
a float here, and it certainly didn't tolerate a struct.
Since this "early C" did not look at the left hand side of the
"." and "->" operators, it really did require different operators
to achieve different effects.

Sort of. x->y is fundamentally equivalent to (*x).y, so you can
always write a program using just one of the two operators. So
in this sense one of the two (usually x->y) can be thought of as
pure syntactic sugar.
These odd aspects of C were fixed
even before the very first C book came out, but -- as with the
"wrong" precedence for the bitwise "&" and "|" operators -- the
historical baggage went along for the ride.

It's not just baggage. C is unique among programming languages
in minimizing the amount of compiler guessing. Some languages
let you write *x in place of x (to use C terminology), or f in
place of f(). (Algol 68 called these guesses "dereferencing" and
"deproceduring", and defined four different kinds of contexts for
disambiguating.) In C, you *can* write f in place of &f (where f
is a function name) and, as of C90 at least, you can write pf(x)
in place of (*pf)(x). With C99 you can write even sin(x) in place
of sinf(x), but the list of generics is strictly bounded.

We could indeed now accept x.y for x a pointer, but keeping both
x->y and x.y is entirely in keeping with the C philosophy of
requiring explicit notation.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
A

Anonymous 7843

Is it a disaster that if foo is a function
pointer you can say foo(1) instead of (*foo)(1)?

Of course it is. Clearly, the syntax for a call through a function
pointer should be foo->(1).
 
C

Clint Olsen

I think the OP was proposing that you could write structxp.fieldf even
when structxp was a pointer to a struct. It's true that the compiler
knows whether the dereference is required, but imo it doesn't fit with C
philosophy (and don't ask me to define that ;-)

It's kind of interesting that the GNU debugger (gdb) has accepted the '.'
syntax for pointers to structs for as long as I can remember.

-Clint
 
T

Tydr Schnubbis

Lew said:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



Nonsense.

Even K&R (1st Edition) admits that the -> notation is 'syntactic sugar' (my
terms). The actual quote from "The C Programming Language" is
"...pointers to structures are so frequently used that the -> notation is
provided as a convenient shorthand."
I don't think he's talking about the fact that astruct->x is a shorthand
for (*astruct).x at all. I think he's just saying that the early
compilers used the syntactical difference between astruct->x and
astruct.x to decide whether to generate instructions that used indirect,
or conversely indirect addressing.
 
T

Tydr Schnubbis

Lew said:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



Nonsense.

Even K&R (1st Edition) admits that the -> notation is 'syntactic sugar' (my
terms). The actual quote from "The C Programming Language" is
"...pointers to structures are so frequently used that the -> notation is
provided as a convenient shorthand."
I don't think he's talking about the fact that astruct->x is a shorthand
for (*astruct).x at all. I think he's just saying that the early
compilers used the syntactical difference between astruct.x and
astruct->x to decide whether to generate instructions that used direct,
or conversely indirect addressing.
 
P

P.J. Plauger

I don't think he's talking about the fact that astruct->x is a shorthand
for (*astruct).x at all. I think he's just saying that the early
compilers used the syntactical difference between astruct.x and
astruct->x to decide whether to generate instructions that used direct,
or conversely indirect addressing.

And I think exactly the opposite.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
K

Keith Thompson

Lew Pitcher said:
Nonsense.

Even K&R (1st Edition) admits that the -> notation is 'syntactic sugar' (my
terms). The actual quote from "The C Programming Language" is
"...pointers to structures are so frequently used that the -> notation is
provided as a convenient shorthand."
[...]

K&R1 was published after the "dark ages". The language had actually
evolved quite a bit by that time. For example, in older versions of
C, all struct member names were in a single namespace, and integer
values could be freely used as pointers. A declaration like
struct {
int member1;
int member2;
};
was actually useful, and enabled expressions like 01234->member2.
(That's why the members of struct tm all have names prefixed with
"tm_".)

I don't know whether pointer and struct expressions were
interchangeable in primordial C, so that foo.member and foo->member
might both be valid but have different meanings, but it's at least
plausible. The quoted statement in K&R1 implies that this is not the
case, but only weakly.
 
A

akarl

P.J. Plauger said:
Some languages let you write *x in place of x (to use C terminology),
or f in place of f().

The second case requires that functions are not first class objects as
in e.g. Pascal. Otherwise we cannot know if f is the result returned by
f or the function itself. It would hence not be possible in C.

-- August
 
R

Richard Tobin

akarl said:
The second case requires that functions are not first class objects as
in e.g. Pascal. Otherwise we cannot know if f is the result returned by
f or the function itself.

No, you just have rules for which contexts they get "deprocedured" in,
as in Algol68 for example.

-- Richard
 
A

akarl

Richard said:
No, you just have rules for which contexts they get "deprocedured" in,
as in Algol68 for example.

Please show us an example of this, where f is a function returning a
function of the same type as f.
 
L

Lawrence Kirby

On Thu, 30 Jun 2005 17:41:15 +0000, CBFalconer wrote:

....
It's a convenience, because of the relative operator precedence.
It is easier and clearer to write:

structxp->fieldf
than
(*structxp).fieldf

This is simply another argument to make * a suffix operator so you would
write:

structxp*.fieldf

:)

Lawrence
 
C

CBFalconer

Tydr said:
.... snip ...

I'm not quite sure what you disagree with. I think you need to
reread the posts, my friend. :)

A says "I don't think foo" and "I think bar", while B says "I think
the opposite", and you are having trouble telling who disagrees
with what!!! I suspect you are in the wrong field.
 
P

P.J. Plauger

I'm not quite sure what you disagree with. I think you need to reread the
posts, my friend. :)

I did, and you're not my friend. The statement in K&R refers to x->y
as "convenient shorthand", which was how I described it. Or you can
call it "syntactic sugar" if you like. The early compilers built a
parse tree for code generation that was not likely to preserve any
difference between x->y and (*x).y. IME, they generated *exactly*
the same code (and pretty good code at that, in the case of Ritchie's
compiler) for either form.

If you're still not sure what I disagree with, reread the above,
my fellow poster.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
C

CBFalconer

Lawrence said:
On Thu, 30 Jun 2005 17:41:15 +0000, CBFalconer wrote:

...


This is simply another argument to make * a suffix operator so
you would write:
structxp*.fieldf
:)

Terrible idea. One more context sensitive usage.
 
R

REH

CBFalconer said:
Terrible idea. One more context sensitive usage.

--
And it would confuse those of us who use both C and C++, because of C++'s .*
and ->* operators.

REH
 

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

No members online now.

Forum statistics

Threads
473,796
Messages
2,569,645
Members
45,371
Latest member
TroyHursey

Latest Threads

Top