Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > late night confusion with -> and .

Reply
Thread Tools

late night confusion with -> and .

 
 
Ark Khasin
Guest
Posts: n/a
 
      01-22-2008
I heard a few times, and may have repeated thoughtlessly, that p->m is
in a way a shorthand for (*p).m
The standard doesn't seem to have a notion of this; this also sounds
downright wrong if p is a pointer to a volatile type.
How common is this misconception?
--
Thanks,
Ark
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      01-22-2008
Ark Khasin <(E-Mail Removed)> writes:

> I heard a few times, and may have repeated thoughtlessly, that p->m is
> in a way a shorthand for (*p).m
> The standard doesn't seem to have a notion of this; this also sounds
> downright wrong if p is a pointer to a volatile type.
> How common is this misconception?


I certainly have this misconception.

I don't immediately see the distinction you're making. Can you
explain further?
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
 
 
 
Ark Khasin
Guest
Posts: n/a
 
      01-22-2008
Ben Pfaff wrote:
> Ark Khasin <(E-Mail Removed)> writes:
>
>> I heard a few times, and may have repeated thoughtlessly, that p->m is
>> in a way a shorthand for (*p).m
>> The standard doesn't seem to have a notion of this; this also sounds
>> downright wrong if p is a pointer to a volatile type.
>> How common is this misconception?

>
> I certainly have this misconception.
>
> I don't immediately see the distinction you're making. Can you
> explain further?

volatile T *p;
(*p) - as in (*p).m - requires actually reading *p, which in turn may
affect the content of *p. p->m only affects the member m.
--
Ark
 
Reply With Quote
 
Ark Khasin
Guest
Posts: n/a
 
      01-22-2008
Ark Khasin wrote:
> Ben Pfaff wrote:
>> Ark Khasin <(E-Mail Removed)> writes:
>>
>>> I heard a few times, and may have repeated thoughtlessly, that p->m is
>>> in a way a shorthand for (*p).m
>>> The standard doesn't seem to have a notion of this; this also sounds
>>> downright wrong if p is a pointer to a volatile type.
>>> How common is this misconception?

>>
>> I certainly have this misconception.
>>
>> I don't immediately see the distinction you're making. Can you
>> explain further?

> volatile T *p;
> (*p) - as in (*p).m - requires actually reading *p, which in turn may
> affect the content of *p. p->m only affects the member m.

And now I am confused even more.
volatile struct T s;
"Natural" s.m requires evaluation (read) of s, doesn't it?
Should I write (&s)->m so as to leave other members unaffected?
--
Ark
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      01-22-2008
Ark Khasin <(E-Mail Removed)> wrote:
> I heard a few times, and may have repeated thoughtlessly,
> that p->m is in a way a shorthand for (*p).m


They are potentially distinct in C++ since one can overload
operators. But that does not apply in C.

> The standard doesn't seem to have a notion of this;


The definitions of these operators seem to, at face value,
imply that relationship. There's even a non-normative
footnote that says (&E)->m is E->m if &E is valid.

> this also sounds downright wrong if p is a pointer to a
> volatile type.


What difference would that make?

> How common is this misconception?


You've yet to demonstrate that it actually is a misconception.

--
Peter
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      01-22-2008
Ark Khasin <(E-Mail Removed)> writes:
> Ben Pfaff wrote:
>> Ark Khasin <(E-Mail Removed)> writes:
>>
>>> I heard a few times, and may have repeated thoughtlessly, that p->m is
>>> in a way a shorthand for (*p).m
>>> The standard doesn't seem to have a notion of this; this also sounds
>>> downright wrong if p is a pointer to a volatile type.
>>> How common is this misconception?

>>
>> I certainly have this misconception.
>>
>> I don't immediately see the distinction you're making. Can you
>> explain further?

> volatile T *p;
> (*p) - as in (*p).m - requires actually reading *p, which in turn may
> affect the content of *p. p->m only affects the member m.


Hmm. The unary * operator yields an lvalue that designates an
object. I suspect that does not necessarily mean that the
contents of the lvalue is read, even by the abstract machine.
But I do not have a citation to offer that confirms that
suspicion. I hope that someone more authoritative has a better
suggestion.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1utchar(a[i&15]);break;}}}
 
Reply With Quote
 
Ark Khasin
Guest
Posts: n/a
 
      01-22-2008
Peter Nilsson wrote:
> Ark Khasin <(E-Mail Removed)> wrote:
>> I heard a few times, and may have repeated thoughtlessly,
>> that p->m is in a way a shorthand for (*p).m

>
> They are potentially distinct in C++ since one can overload
> operators. But that does not apply in C.
>
>> The standard doesn't seem to have a notion of this;

>
> The definitions of these operators seem to, at face value,
> imply that relationship. There's even a non-normative
> footnote that says (&E)->m is E->m if &E is valid.
>
>> this also sounds downright wrong if p is a pointer to a
>> volatile type.

>
> What difference would that make?
>
>> How common is this misconception?

>
> You've yet to demonstrate that it actually is a misconception.
>
> --
> Peter

Indeed, thank you for pointing out the Footnote 79) If &E is a valid
pointer expression (where & is the ‘‘address-of ’’ operator, which
generates a pointer to its operand), the expression (&E)->MOS is the
same as E.MOS.
I honestly don't know how to read it: an expression has a value and side
effects. No-one argues with the values part. It's the side effects that
bother me...
--
Ark

 
Reply With Quote
 
Ark Khasin
Guest
Posts: n/a
 
      01-22-2008
Ben Pfaff wrote:
> Ark Khasin <(E-Mail Removed)> writes:
>> Ben Pfaff wrote:
>>> Ark Khasin <(E-Mail Removed)> writes:
>>>
>>>> I heard a few times, and may have repeated thoughtlessly, that p->m is
>>>> in a way a shorthand for (*p).m
>>>> The standard doesn't seem to have a notion of this; this also sounds
>>>> downright wrong if p is a pointer to a volatile type.
>>>> How common is this misconception?
>>> I certainly have this misconception.
>>>
>>> I don't immediately see the distinction you're making. Can you
>>> explain further?

>> volatile T *p;
>> (*p) - as in (*p).m - requires actually reading *p, which in turn may
>> affect the content of *p. p->m only affects the member m.

>
> Hmm. The unary * operator yields an lvalue that designates an
> object. I suspect that does not necessarily mean that the
> contents of the lvalue is read, even by the abstract machine.
> But I do not have a citation to offer that confirms that
> suspicion. I hope that someone more authoritative has a better
> suggestion.

My naive thinking is that if
volatile unsigned char *uart_receive;
*uart_receive; //discard the character, clear the interrupt source
is a valid practice, then unary * does evaluate (read) the value.
Similarly,
volatile uart_t *uart;
uart->receive; //discard the character, clear the interrupt source
But then
(*uart).receive;
seems to do a lot more of unwanted stuff.

--
Ark

 
Reply With Quote
 
user923005
Guest
Posts: n/a
 
      01-22-2008
On Jan 21, 8:47*pm, Ark Khasin <(E-Mail Removed)> wrote:
> I heard a few times, and may have repeated thoughtlessly, that p->m is
> in a way a shorthand for (*p).m
> The standard doesn't seem to have a notion of this; this also sounds
> downright wrong if p is a pointer to a volatile type.


If you have an object, and you want to change a member, then it is:
p.m = foo;

If you have a pointer to an object, and you want to change a member,
then it is either:
p->m = foo;
Or:
(*p).m = foo;

Nobody uses the second form. Everyone uses the first form. I don't
know why it came out that way, but if you write (*p).m you will get
raised eyebrows, even though they are totally equivalent expressions.


> How common is this misconception?


Really, really rare.
 
Reply With Quote
 
christian.bau
Guest
Posts: n/a
 
      01-22-2008
On Jan 22, 6:13*am, Ark Khasin <(E-Mail Removed)> wrote:
> Ben Pfaff wrote:
> > Ark Khasin <(E-Mail Removed)> writes:
> >> Ben Pfaff wrote:
> >>> Ark Khasin <(E-Mail Removed)> writes:

>
> >>>> I heard a few times, and may have repeated thoughtlessly, that p->m is
> >>>> in a way a shorthand for (*p).m
> >>>> The standard doesn't seem to have a notion of this; this also sounds
> >>>> downright wrong if p is a pointer to a volatile type.
> >>>> How common is this misconception?
> >>> I certainly have this misconception.

>
> >>> I don't immediately see the distinction you're making. *Can you
> >>> explain further?
> >> volatile T *p;
> >> (*p) - as in (*p).m - requires actually reading *p, which in turn may
> >> affect the content of *p. p->m only affects the member m.

>
> > Hmm. *The unary * operator yields an lvalue that designates an
> > object. *I suspect that does not necessarily mean that the
> > contents of the lvalue is read, even by the abstract machine.
> > But I do not have a citation to offer that confirms that
> > suspicion. *I hope that someone more authoritative has a better
> > suggestion.

>
> My naive thinking is that if
> * * volatile unsigned char *uart_receive;
> * * *uart_receive; //discard the character, clear the interrupt source
> is a valid practice, then unary * does evaluate (read) the value.


Severe warning here: This is one of the few places with a very severe
and very non-obvious between C and C++. Don't do this if you ever want
to reuse the same code in a C++ program (or you expect that someone
else _might_ want to do this in ten years time).

In one language, an lvalue-to-rvalue conversion takes place, which
accesses *uart_receive. In the other language, no such conversion
takes place, and there is no access. Better write "unsigned char dummy
= *uart_receive; ". (And I don't know which language does the access
and which one doesn't, the distinction is sufficiently obscure that
writing *uart_receive alone is a bug in each language).

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: I stayed up too late last night ...... Mike Easter Computer Support 2 11-04-2010 02:24 PM
Re: I stayed up too late last night ...... OldGringo38 Computer Support 0 11-04-2010 01:30 PM
Some late night metaprogramming Trans Ruby 0 04-02-2008 06:05 AM
Late night beginners question =?Utf-8?B?Qi4gQ2hlcm5pY2s=?= ASP .Net 4 07-31-2005 05:04 PM
DVD Verdict reviews: THE PRINCE AND ME, LATE NIGHT WITH CONAN O'BRIEN 10TH ANNIVERSARY SPECIAL, and more! DVD Verdict DVD Video 0 08-31-2004 09:08 AM



Advertisments