473,403 Members | 2,222 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,403 software developers and data experts.

why use -> (not .) with pointers?

Hi,

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

Felix
Nov 15 '05 #1
53 2346


Felix Kater wrote:
Hi,

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

-> is used when you have a pointer to a struct, and you are trying to
access
elements of the struct whose address is stored in the pointer.

.. is used when you have an object of a struct, and you are trying to
access
elements of the struct.

Does that help?

Nov 15 '05 #2
Felix Kater wrote:
Hi,

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

Felix

I think the answer is NO, there aren't any reasons why
the distinction exists since the compiler can always
figure it out.

If we would always use '.' and there was a pointer, the
compiler could test if we have instead of a structure,
a pointer to a structure, then generate a dereferencing of
the pointer without much trouble.

The best way to do this is to deprecate '->'

But, helas, this is not going to happen any time soon.

jacob

Nov 15 '05 #3
Suman wrote:

Felix Kater wrote:
Hi,

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?


-> is used when you have a pointer to a struct, and you are trying to
access
elements of the struct whose address is stored in the pointer.

. is used when you have an object of a struct, and you are trying to
access
elements of the struct.

Does that help?


You didn't answer the question!
Are there cases in which the
compiler couldn't figure out what to do?


My answer is no. See elsewhere in this thread
Nov 15 '05 #4
In article <11*********************@f14g2000cwb.googlegroups. com>,
Suman <sk*****@gmail.com> wrote:
-> is used when you have a pointer to a struct, and you are trying to
access elements of the struct whose address is stored in the pointer.

. is used when you have an object of a struct, and you are trying to
access elements of the struct.


I think the original poster knows that. Since there is no context
where both a.b and a->b are legal, he is asking why C doesn't use the
same syntax for both.

I think the answer is just that they are different operations so C has
different names for them. a->b is equivalent to (*a).b. A less
explicit language than C might confound these, but C doesn't.

-- Richard

Nov 15 '05 #5
Felix Kater wrote:
when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ?
Historical. I seem to recall . came first, -> came later.
Are there cases in which the compiler couldn't figure out what to do?


If the language definition said that . would dereferece
pointers, or that -> would work on structures, the compiler
would have no problem implementing it.

Whether that was true for the original implementation of
C (which, do remember, worked in a environment where the
amount of available memory wouldn't even be enough for a
decent *image* on today's machines), I don't know.

It's not likely to change.

--
Chris "electric hedgehog" Dollin
It's called *extreme* programming, not *stupid* programming.
Nov 15 '05 #6


Richard Tobin wrote:
[snip]

I think the answer is just that they are different operations so C has
different names for them. a->b is equivalent to (*a).b. Don't you think that was what I meant, albeit in a roundabout way?
You don't I'll assume for now :)

<i_think_remotely_O(n)T(opic)>
In any case, this fires my curiosity. What if we did have the _same_
operator? Would the compiler not have to extra work?
</i_think_remotely_O(n)T(opic)> A less
explicit language than C might confound these, but C doesn't.


Nov 15 '05 #7


Richard Tobin wrote:
[snip]

I think the answer is just that they are different operations so C has
different names for them. a->b is equivalent to (*a).b. Don't you think that was what I meant, albeit in a roundabout way?
You don't I'll assume for now :)

<i_think_remotely_O(n)T(opic)>
In any case, this fires my curiosity. What if we did have the _same_
operator? Would the compiler not have to do extra work?
</i_think_remotely_O(n)T(opic)> A less
explicit language than C might confound these, but C doesn't.


Nov 15 '05 #8
On Thu, 30 Jun 2005 07:14:37 -0700, Suman wrote:


Richard Tobin wrote:
[snip]

I think the answer is just that they are different operations so C has
different names for them. a->b is equivalent to (*a).b.

Don't you think that was what I meant, albeit in a roundabout way?
You don't I'll assume for now :)

<i_think_remotely_O(n)T(opic)>
In any case, this fires my curiosity. What if we did have the _same_
operator? Would the compiler not have to do extra work?


Not to any measurable degree. It has to validate the type of the left hand
operand either way.

Lawrence
Nov 15 '05 #9
On Thu, 30 Jun 2005 15:21:16 +0200, jacob navia wrote:
Felix Kater wrote:
Hi,

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

Felix I think the answer is NO, there aren't any reasons why
the distinction exists since the compiler can always
figure it out.


True.
If we would always use '.' and there was a pointer, the
compiler could test if we have instead of a structure,
a pointer to a structure, then generate a dereferencing of
the pointer without much trouble.
True.
The best way to do this is to deprecate '->'

But, helas, this is not going to happen any time soon.


That assumes that this is a sensible and desirable thing to do. It would
make the language syntax marginally simpler, whereas the existing ->
operator highlights the fact that you are using a pointer, which IMO is no
bad thing in C.

Lawrence

Nov 15 '05 #10
Felix Kater <f.******@gmx.net> wrote:

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?


Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.

-Larry Jones

It's no fun to play games with a poor sport. -- Calvin
Nov 15 '05 #11
la************@ugs.com wrote:
Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.


To me, it's still essential syntactically speaking.

Letting the compiler "guess" what you mean is a really, really bad idea
in general. Even when the case seems obvious to you.
Nov 15 '05 #12
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

la************@ugs.com wrote:
Felix Kater <f.******@gmx.net> wrote:
when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.


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."

This, in reference to an example of the use of pointers to structures, which
points out that, given

struct date {
int day;
int month;
int year;
int yearday;
char mon_name[4];
};
and
struct date *pd;
then
pd->year
is exactly the same as
(*pd).year
- --
Lew Pitcher
IT Specialist, Enterprise Data Systems,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFCxBuYagVFX4UWr64RAt02AKCZe0YXskg4oZ+UrPYPXm qtyTHXhgCg5uRk
W0SnNGl1N0ZayPZGkQC+qrs=
=Ckpm
-----END PGP SIGNATURE-----
Nov 15 '05 #13
In article <42*********************@news.club-internet.fr>,
Guillaume <"grsNOSPAM at NOTTHATmail dot com"> wrote:
To me, it's still essential syntactically speaking.

Letting the compiler "guess" what you mean is a really, really bad idea
in general. Even when the case seems obvious to you.


So would you favour having different operators for integer and
floating-point addition? Is it a disaster that if foo is a function
pointer you can say foo(1) instead of (*foo)(1)?

Why is determining the action "guessing" in this case but not the
others?

-- Richard

Nov 15 '05 #14
Richard Tobin wrote:
So would you favour having different operators for integer and
floating-point addition?
Actually, that could be debatable.
When I see so many programmers mixing integers and fp numbers in
expressions without quite knowing what they are doing (and sometimes
wondering why the heck they don't get the results they are expecting),
I'm thinking: why not different operators. At least, that would force
you to have a clear understanding of both what you want and what is
going to happen, without having to read dozens of pages of the standard
and praying that your compiler sticks to it...
Is it a disaster that if foo is a function
pointer you can say foo(1) instead of (*foo)(1)?
You're making a point, but I don't see this as harmful as the "./->"
case. When you see foo(1), you immediately know while reading it
that foo is either a pointer to a function, or a function symbol.
There is no "function type" that you can use in C as a variable;
there are only function pointers. Functions themselves cannot be
C variables, just as you can't "instantiate" a void variable;
only pointers to void are legal.

Since I almost never use a pointer to function without checking
first if it's NULL or not, it's immediately clear what 'foo' is,
without having to browse through hundreds of lines of code...
Why is determining the action "guessing" in this case but not the
others?


In the case of using '.' instead of '->' for pointers to structures,
you loose sight of what the variable type is: is it a pointer to
a structure or a structure? That hinders readability in my opinion.

Then again, I use the Hungarian notation most of the time, so that
would not be that big a deal for me: but I know a lot of programmers
that don't. Then the source code would become hell to read.

High-level languages are meant to be highly readable by you and
by others. Readability should be a big part of programming.
Apparent syntax simplifications do more harm than good in my opinion.
In that particular case, that would tend to make the newer programmers
confuse pointer-types with non-pointer-types. And that would tend
to just plain confuse the more seasoned ones...
Nov 15 '05 #15
jacob navia wrote:
Felix Kater wrote:

when accessing the variables in a struct: What's the reason why
in C newline you have -> and . instead of only . ? Are there
cases in which the compiler couldn't figure out what to do?


I think the answer is NO, there aren't any reasons why the
distinction exists since the compiler can always figure it out.

If we would always use '.' and there was a pointer, the compiler
could test if we have instead of a structure, a pointer to a
structure, then generate a dereferencing of the pointer without
much trouble.


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

structxp->fieldf
than
(*structxp).fieldf

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 15 '05 #16
In article <42*********************@news.club-internet.fr>,
Guillaume <"grsNOSPAM at NOTTHATmail dot com"> wrote:
When I see so many programmers mixing integers and fp numbers in
expressions without quite knowing what they are doing (and sometimes
wondering why the heck they don't get the results they are expecting),
I'm thinking: why not different operators. At least, that would force
you to have a clear understanding of both what you want and what is
going to happen, without having to read dozens of pages of the standard
and praying that your compiler sticks to it...


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...
--
Warning: potentially contains traces of nuts.
Nov 15 '05 #17
In article <20******************************@gmx.net>,
Felix Kater <f.******@gmx.net> wrote:

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ?


I think it's at least partially historical. Most other languages of
the time (mid seventies) were making the distinction between pointing
and membership, perhaps less for utilitarian reasons and more because
there was a perception (at the time) that pointers were a difficult
concept for computer science students to grasp. Having a distinct
syntax (one which actually has a "pointy" symbol) may have been helpful
in that area.
--
7842++
Nov 15 '05 #18
>Felix Kater <f.******@gmx.net> wrote:
when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

In article <fr************@jones.homeip.net>
<la************@ugs.com> gives the correct answer:Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.


but it might serve to be a bit more detailed.

The "true need" for separate "." and "->" operators went away
sometime around 1978 or 1979, around the time the original K&R
white book came out.

Before then, Dennis' early compilers accepted things like this:

struct { char a, b; };
int x 12345; /* yes, no "=" sign */

main() {
printf("%d is made up of the bytes %d and %d\n", x,
(x.a) & 0377, (x.b) & 0377);
}

(in fact, in an even-earlier version of the compiler, the syntax
was "struct (" rather than "struct {". The syntax above is what
appeared in V6 Unix. I have read V6 code, but never used the V6
C compiler myself.)

Note that we have taken the "a" and "b" elements of a plain
"int", not the "struct" that contains them. The "." operator
works on *any* lvalue, in this early C, and all the structure
member names must be unique -- no other struct can have members
named "a" and "b".

We can (and people did) also write things like:

struct rkreg { unsigned rkcsr, rkdar, rkwc; };
...
/* read disk sector(s) */
0777440->rkdar = addr;
0777440->rkwc = -(bytecount / 2);
0777440->rkcsr = RK_READ | RK_GO;

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

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. 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.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '05 #19


Walter Roberson wrote:

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.
FORTRAN II was like this: An expression had to be
entirely integer or entirely floating-point. Assignment
(which FORTRAN didn't think of as an "operator") could
convert types: INT = REAL or REAL = INT were valid, but
INT + REAL was not.

When FORTRAN IV came along and allowed mixed expressions
my initial reaction was "Why? We've been getting along
fine without them." It didn't take me long to change my
mind, though, and I would not want to return to the old days.
Such a scheme might do interesting things to expressions such as
toupper(HexChar) - 'A' + 10
due to the signed-ness ambiguity of char...


The signedness of `char' does not affect this expression
because the three operands are all of type `int'. The type
of `HexChar' is not shown, but if its value is in fact one of
the letters 'a' through 'f' or 'A' through 'F' then that value
is positive even if `char' is signed.

(Note that the expression is not a bulletproof way to
derive a hex digit's value from a letter, even if the letter
is known to be valid. The codes for these letters need not
be ascending, nor even adjacent. I know of no encoding where
they aren't -- but at least one encoding where 'A' + 25 != 'Z'
exists and is in current use, so there's at least a potential
for unpleasant surprises.)

--
Er*********@sun.com

Nov 15 '05 #20
On 2005-06-30 13:56:20 -0400, ro******@ibd.nrc-cnrc.gc.ca (Walter
Roberson) said:
In article <42*********************@news.club-internet.fr>,
Guillaume <"grsNOSPAM at NOTTHATmail dot com"> wrote:
When I see so many programmers mixing integers and fp numbers in
expressions without quite knowing what they are doing (and sometimes
wondering why the heck they don't get the results they are expecting),
I'm thinking: why not different operators. At least, that would force
you to have a clear understanding of both what you want and what is
going to happen, without having to read dozens of pages of the standard
and praying that your compiler sticks to it...


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. ;)

--
Clark S. Cox, III
cl*******@gmail.com

Nov 15 '05 #21
On Thu, 30 Jun 2005 17:41:15 GMT, CBFalconer <cb********@yahoo.com>
wrote:
jacob navia wrote:
Felix Kater wrote:

when accessing the variables in a struct: What's the reason why
in C newline you have -> and . instead of only . ? Are there
cases in which the compiler couldn't figure out what to do?


I think the answer is NO, there aren't any reasons why the
distinction exists since the compiler can always figure it out.

If we would always use '.' and there was a pointer, the compiler
could test if we have instead of a structure, a pointer to a
structure, then generate a dereferencing of the pointer without
much trouble.


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 ;-)

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 15 '05 #22
On 30 Jun 2005 16:36:32 GMT, ri*****@cogsci.ed.ac.uk (Richard Tobin)
wrote:
In article <42*********************@news.club-internet.fr>,
Guillaume <"grsNOSPAM at NOTTHATmail dot com"> wrote:
To me, it's still essential syntactically speaking.

Letting the compiler "guess" what you mean is a really, really bad idea
in general. Even when the case seems obvious to you.
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.
Is it a disaster that if foo is a function
pointer you can say foo(1) instead of (*foo)(1)?

Why is determining the action "guessing" in this case but not the
others?

-- Richard


--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 15 '05 #23
"Chris Torek" <no****@torek.net> wrote in message
news:da*********@news4.newsguy.com...
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
Nov 15 '05 #24
In article <da**********@pc-news.cogsci.ed.ac.uk>,
Richard Tobin <ri*****@cogsci.ed.ac.uk> wrote:

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).
--
7842++
Nov 15 '05 #25
On 2005-06-30, Alan Balmer <al******@att.net> wrote:
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
Nov 15 '05 #26
Lew Pitcher wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

la************@ugs.com wrote:
Felix Kater <f.******@gmx.net> wrote:
when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.


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.
Nov 15 '05 #27
Lew Pitcher wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

la************@ugs.com wrote:
Felix Kater <f.******@gmx.net> wrote:
when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.


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.
Nov 15 '05 #28
"Tydr Schnubbis" <fa**@address.dude> wrote in message
news:I3******************@juliett.dax.net...
Lew Pitcher wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

la************@ugs.com wrote:
Felix Kater <f.******@gmx.net> wrote:

when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?
Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.


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.


And I think exactly the opposite.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 15 '05 #29
Lew Pitcher <Le*********@td.com> writes:
la************@ugs.com wrote:
Felix Kater <f.******@gmx.net> wrote:
when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ? Are there cases in which the
compiler couldn't figure out what to do?

Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.


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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #30
P.J. Plauger wrote:
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
Nov 15 '05 #31
In article <vN*********************@newsc.telia.net>,
akarl <fu********@comhem.se> wrote:
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
Nov 15 '05 #32
On Thu, 30 Jun 2005 19:00:27 GMT,
Anonymous 7843 <an******@example.com> wrote:

In article <da**********@pc-news.cogsci.ed.ac.uk>,
Richard Tobin <ri*****@cogsci.ed.ac.uk> wrote:

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).


That is a bit perl'ish, isn't it.

Villy
Nov 15 '05 #33
P.J. Plauger wrote:
"Tydr Schnubbis" <fa**@address.dude> wrote in message
news:I3******************@juliett.dax.net...
Lew Pitcher wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

la************@ugs.com wrote:
Felix Kater <f.******@gmx.net> wrote:

>when accessing the variables in a struct: What's the reason why in C
>you have -> and . instead of only . ? Are there cases in which the
>compiler couldn't figure out what to do?
Not anymore. But back in the dark ages, C was much less concerned about
types than it is today and would allow pretty much *anything* as the
left operand of . or ->. In that environment, the compiler couldn't
figure out what to do, so having two different operators was essential.

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.


And I think exactly the opposite.

I'm not quite sure what you disagree with. I think you need to reread
the posts, my friend. :)
Nov 15 '05 #34
Richard Tobin wrote:
In article <vN*********************@newsc.telia.net>,
akarl <fu********@comhem.se> wrote:

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.


Please show us an example of this, where f is a function returning a
function of the same type as f.
Nov 15 '05 #35
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

Nov 15 '05 #36
Tydr Schnubbis wrote:
P.J. Plauger wrote:
"Tydr Schnubbis" <fa**@address.dude> wrote in message

.... snip ...
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.


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.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 15 '05 #37
"Tydr Schnubbis" <fa**@address.dude> wrote in message
news:Fw******************@juliett.dax.net...
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.
And I think exactly the opposite.

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
Nov 15 '05 #38
Lawrence Kirby wrote:
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
:-)


Terrible idea. One more context sensitive usage.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 15 '05 #39
REH

"CBFalconer" <cb********@yahoo.com> wrote in message
news:42***************@yahoo.com...
Lawrence Kirby wrote:
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
:-)


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
Nov 15 '05 #40
In article <rA*******************@newsb.telia.net>,
akarl <fu********@comhem.se> wrote:
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.


I'm not sure such a thing can be declared in Algol68 any more than
it can in C.

-- Richard
Nov 15 '05 #41
P.J. Plauger wrote:
"Tydr Schnubbis" <fa**@address.dude> wrote in message
news:Fw******************@juliett.dax.net...
> 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.

And I think exactly the opposite.
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.

Yes, noone has disputed the 'syntactic sugar' part.
If you're still not sure what I disagree with, reread the above,
my fellow poster.


Just to make it clear, there are two issues here:

#1) s->x is a shorthand for (*s).x

#2) early compilers used the difference between s->x and s.x to know
whether to generate code using indirect or direct addressing

la************@ugs.com was stating #2 as a fact. Lew Pitcher, thinking
he instead was disputing #1, replied rather harshly. I think everyone
can see that he misread the post he replied to. They are talking about
two different, but related aspects of the C syntax.

I sometimes misread posts, too. But I still haven't had the 'pleasure'
of people supporting me even when I'm wrong. This discussion is getting
a bit childish now, which I'll be the first to admit. ;)
Nov 15 '05 #42
CBFalconer wrote:
Tydr Schnubbis wrote:
P.J. Plauger wrote:
"Tydr Schnubbis" <fa**@address.dude> wrote in message

... snip ...

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.


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.

I was trying to be polite. Being more direct is sometimes a bit on the
offensive side. But the idea is they were talking about two different
things, so they didn't really seem disagree at all. Can happen to
anyone, including myself. I have explained in a reply to plauger.
Nov 15 '05 #43
C is a language and therefore must have rules. In English we say A
book and AN elephant. It may be easier on our part to just use A in
both cases, but that's not so.

I think more than anything -> helps us as programmers remember that we
are dealing with a pointer to a struct and not the struct itself. Sure
the compiler could figure it out, but it may be difficult for us to
figure it out. Why? Because we are allowing . to mean two different
things. Making a distinction helps us more than the program. It all
turns into 1's and 0's after all and . and -> don't have much meaning
to the processor :)

Nov 15 '05 #44
Me
> >Letting the compiler "guess" what you mean is a really, really bad idea
in general. Even when the case seems obvious to you.
So would you favour having different operators for integer and
floating-point addition?


No, but I might favor not being able to implicitly convert between one
and the other. Ditto for char/enums to/from integers and _Bool to other
types.
Is it a disaster that if foo is a function
pointer you can say foo(1) instead of (*foo)(1)?
Yes, the second form should be eliminated from the language IMHO.
Function names decompose to regular pointers the same way that arrays
of T decompose to pointers to T (but even worse) so you can do:

(*&******&*****printf)("hi");

if you really wanted to. The () on the rhs is the thing that does the
dereference the same way that [] on a pointer does a dereference.
Why is determining the action "guessing" in this case but not the
others?


Using . because there is no ambiguity hides a dereference when there
really is one. Like keeping track of pointers in code wasn't hard
enough.

Nov 15 '05 #45
Me
> when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ?


Convienience and consistency.

a->b->c

is a shortcut for

(*(*a).b).c

If you let that expression be expressed as:

a.b.c

due to the lack of ambiguity, it makes it look like the pointer gets
auto dereferenced which is *really* crappy from a grep and a code
reading standpoint. Also imagine the case where 'a' was a pointer to a
pointer:

(*a).b.c

would be a shortcut for:

(**a).b.c

Which seems like a really insane thing to do just because there is no
ambiguity. Other languages don't have this problem because you can't
create pointers to pointers and their types are automatically
dereferenced. But these languages have an ambiguity with assignment
(assuming they're imperative languages) so they need a way to
distinguish between reseating a pointer and making a copy of a value.

Nov 15 '05 #46
REH

"Me" <an*****************@yahoo.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
when accessing the variables in a struct: What's the reason why in C
you have -> and . instead of only . ?


Convienience and consistency.

a->b->c

is a shortcut for

(*(*a).b).c

If you let that expression be expressed as:

a.b.c

due to the lack of ambiguity, it makes it look like the pointer gets
auto dereferenced which is *really* crappy from a grep and a code
reading standpoint. Also imagine the case where 'a' was a pointer to a
pointer:

(*a).b.c

would be a shortcut for:

(**a).b.c

Which seems like a really insane thing to do just because there is no
ambiguity. Other languages don't have this problem because you can't
create pointers to pointers and their types are automatically
dereferenced. But these languages have an ambiguity with assignment
(assuming they're imperative languages) so they need a way to
distinguish between reseating a pointer and making a copy of a value.


Explain to me how Ada, which allows pointers to pointers, doesn't
automatically dereference, only used . (not ->), and is an imperative
language, has any ambiguity with assignment (hint: it doesn't).

REH
Nov 15 '05 #47
Me
> > Other languages don't have this problem because you can't
create pointers to pointers and their types are automatically
dereferenced. But these languages have an ambiguity with assignment
(assuming they're imperative languages) so they need a way to
distinguish between reseating a pointer and making a copy of a value.


Explain to me how Ada, which allows pointers to pointers, doesn't
automatically dereference, only used . (not ->), and is an imperative
language, has any ambiguity with assignment (hint: it doesn't).


I think you already explained it yourself. I said in languages that
don't allow pointers to pointers and that automatically dereference
have this ambiguity. I don't really mean ambiguity in a strict sense, I
mean it in that they need a way to distinguish between reseating a
pointer and making a copy somehow. It could be something as trivial as:

// explicitly making a copy
a = b; // this does a reseat
a = copy(b); // reseats but creates a copy first

or

// two different operators
a = b; // copies value
a := b; // reseat

which isn't really that profound as reseating and copying values are
basic operations in any useful imperative language. The worst are
languages that provide primitive types using value semantics and UDTs
using reference semantics and hiding it behind copy on write. It's very
easy to come up with examples that show inconsistencies in their type
system but I'm already getting way off topic here.

Nov 15 '05 #48
P.J. Plauger <pj*@dinkumware.com> wrote:

"Chris Torek" <no****@torek.net> wrote in message
news:da*********@news4.newsguy.com...
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.


On the other hand, I seem to recall that the "." operator would, indeed,
take *any* lvalue on the left. Does that match your recollection?

-Larry Jones

I think football is a sport the way ducks think hunting is a sport. -- Calvin
Nov 15 '05 #49
<la************@ugs.com> wrote in message
news:3b************@jones.homeip.net...
P.J. Plauger <pj*@dinkumware.com> wrote:

"Chris Torek" <no****@torek.net> wrote in message
news:da*********@news4.newsguy.com...
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.


On the other hand, I seem to recall that the "." operator would, indeed,
take *any* lvalue on the left. Does that match your recollection?


Could be. Early C was pretty wild and wooly.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 15 '05 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: glen stark | last post by:
Hi all. I'm working with an array of member function pointers (they are all get function of the class Bead). The typedef is: typedef _real (Bead::*_beadGfp)(void); I have a class System...
11
by: Scott Brady Drummonds | last post by:
Hi, everyone, I've checked a couple of on-line resources and am unable to determine how reinterpret_cast<> is different from static_cast<>. They both seem to perform a compile-time casting of...
8
by: maths_fan | last post by:
Can't understand how to overload these operations and for what reason?
3
by: H. S. | last post by:
Hi, I am trying to compile these set of C++ files and trying out class inheritence and function pointers. Can anybody shed some light why my compiler is not compiling them and where I am going...
13
by: Jon Slaughter | last post by:
I was wondering if there is any big difference(speed/size) when one uses -> vs . as returning a pointer vs a reference. i..e in my code I overload a lot(cause I have many classes) and I can do...
6
by: PengYu.UT | last post by:
Hi, Suppose I have a list which contains pointers. I want the pointer got by dereferencing the iterator be a pointer pointing to a const object. But std::list<const T*>::const_iterator doens't...
2
by: eb | last post by:
I have this working code : foo.h /* nothing */ foo.cpp ... std::vector<std::vector<T * my_T(board_size,board_size) ; for (i=0; i<board_size; i++)
43
by: john | last post by:
Hi, in TC++PL 3 on pages 674-675 it is mentioned: "Maybe your first idea for a two-dimensional vector was something like this: class Matrix { valarray< valarray<doublev; public: // ... };
6
by: gsBytes | last post by:
I am working with a specialized graph class, which has a node class and an edge class. In the node class, there is a list of pointers to each edge. Code that uses the graph must be able to see what...
12
by: eiji.anonremail | last post by:
Hi all, I'm facing some uncertainty with const template arguments. Maybe someone could explain the general strategy. #include <vector> int main(int arc, char** argv) {
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.