Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #95168 > unrolled thread

pointers

Started byasetofsymbols@gmail.com
First post2016-10-23 08:11 -0700
Last post2016-10-24 13:34 -0700
Articles 15 on this page of 55 — 12 participants

Back to article view | Back to comp.lang.c


Contents

  pointers asetofsymbols@gmail.com - 2016-10-23 08:11 -0700
    Re: pointers Richard Heathfield <rjh@cpax.org.uk> - 2016-10-23 16:26 +0100
      Re: pointers asetofsymbols@gmail.com - 2016-10-23 10:35 -0700
        Re: pointers Ike Naar <ike@iceland.freeshell.org> - 2016-10-23 17:47 +0000
          Re: pointers asetofsymbols@gmail.com - 2016-10-25 12:55 -0700
        Re: pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2016-10-23 13:58 -0400
          Re: pointers BartC <bc@freeuk.com> - 2016-10-24 00:55 +0100
            Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-23 17:27 -0700
              Re: pointers BartC <bc@freeuk.com> - 2016-10-24 11:53 +0100
                Re: pointers supercat@casperkitty.com - 2016-10-24 07:29 -0700
                  Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-24 08:55 -0700
                  Re: pointers Tim Rentsch <txr@alumni.caltech.edu> - 2016-10-24 14:02 -0700
                    Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-24 14:42 -0700
                      Re: pointers Tim Rentsch <txr@alumni.caltech.edu> - 2016-10-25 08:56 -0700
                        Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-25 12:17 -0700
                          Re: pointers Tim Rentsch <txr@alumni.caltech.edu> - 2016-10-26 06:37 -0700
                Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-24 08:49 -0700
                  Re: pointers BartC <bc@freeuk.com> - 2016-10-24 17:25 +0100
                    Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-24 09:52 -0700
                      Re: pointers BartC <bc@freeuk.com> - 2016-10-24 18:15 +0100
                        Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-24 12:20 -0700
                          Re: pointers BartC <bc@freeuk.com> - 2016-10-24 20:58 +0100
                            Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-24 13:16 -0700
                              Re: pointers BartC <bc@freeuk.com> - 2016-10-24 23:53 +0100
                                Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-25 13:38 -0700
                                  Re: pointers BartC <bc@freeuk.com> - 2016-10-25 23:06 +0100
                                    Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-25 15:39 -0700
                                      Re: pointers BartC <bc@freeuk.com> - 2016-10-26 00:26 +0100
                                        Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-25 16:44 -0700
                                          Re: pointers BartC <bc@freeuk.com> - 2016-10-26 01:02 +0100
                                            Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-25 17:35 -0700
                                    Re: pointers Ike Naar <ike@iceland.freeshell.org> - 2016-10-26 06:27 +0000
                                      Re: pointers BartC <bc@freeuk.com> - 2016-10-26 12:47 +0100
                                        Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-26 09:05 -0700
                                          Re: pointers BartC <bc@freeuk.com> - 2016-10-26 18:46 +0100
                                            Re: pointers supercat@casperkitty.com - 2016-10-26 11:44 -0700
                                              Re: pointers BartC <bc@freeuk.com> - 2016-10-26 20:12 +0100
                                                Re: pointers BartC <bc@freeuk.com> - 2016-10-26 20:30 +0100
                                                Re: pointers supercat@casperkitty.com - 2016-10-26 13:02 -0700
                                            Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-26 11:52 -0700
                                        Re: pointers Ike Naar <ike@iceland.freeshell.org> - 2016-10-26 19:11 +0000
                                          Re: pointers BartC <bc@freeuk.com> - 2016-10-26 21:25 +0100
                                Re: pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2016-10-25 18:56 -0400
                                  Re: pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2016-10-25 19:12 -0400
                                  Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-25 16:31 -0700
                        Re: pointers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-24 21:36 +0100
                          Re: pointers BartC <bc@freeuk.com> - 2016-10-25 16:54 +0100
                            Re: pointers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-25 19:09 +0100
                      Re: pointers supercat@casperkitty.com - 2016-10-24 11:33 -0700
                        Re: pointers Keith Thompson <kst-u@mib.org> - 2016-10-24 12:22 -0700
            Re: pointers James Kuyper <jameskuyper@verizon.net> - 2016-10-24 10:23 -0400
    Re: pointers "James R. Kuyper" <jameskuyper@verizon.net> - 2016-10-23 12:31 -0400
      Re: pointers Richard Heathfield <rjh@cpax.org.uk> - 2016-10-23 17:38 +0100
    Re: pointers Lorinczy Zsigmond <zsiga@nospam.for.me> - 2016-10-24 14:02 +0200
    Re: pointers John Bode <jfbode1029@gmail.com> - 2016-10-24 13:34 -0700

Page 3 of 3 — ← Prev page 1 2 [3]


#95333

FromIke Naar <ike@iceland.freeshell.org>
Date2016-10-26 19:11 +0000
Message-ID<slrn3vfso12006.g75.ike@iceland.freeshell.org>
In reply to#95324
On 2016-10-26, BartC <bc@freeuk.com> wrote:
> On 26/10/2016 07:27, Ike Naar wrote:
>> On 2016-10-25, BartC <bc@freeuk.com> wrote:
>>> You don't need to explain why &*p is allowed
>>> but not & &**p or *&p!
>>
>> What makes you believe that *&p is not allowed?
>
> OK that one is allowed:
>
> *&*&*&*p;
>
> as is:
>
> &*&*&*p;
>
> when p is a pointer. But not:
>
> ***& & &p;
>
> or:
>
> & & &***p;  // allowed on some compilers when p is T***
>
> If, however, you go through this on paper, striking through * followed 
> by &, or & followed by * with a pencil, and repeating, you end up with 
> just 'p' in all cases. And p doesn't need to be a pointer.
>
> On paper.

This all seems to be a non-issue.  When writing code, one doesn't
concatenate tokens at random, one writes with a purpose. What would
be the purpose of writing '* * * & & & p' instead of 'p' ?

Let me give you a similar example: unary minuses cancel out,
so, for, say, double x, -(-x) and x denote the same value.
Yet one can write 'x = 4.2;' but not '-(-x) = 4.2;'.
So '-(-x)' and 'x' are not always interchangable, although unary minuses
cancel out.
Do you think this is a problem?

[toc] | [prev] | [next] | [standalone]


#95337

FromBartC <bc@freeuk.com>
Date2016-10-26 21:25 +0100
Message-ID<nur3eq$16b$1@dont-email.me>
In reply to#95333
On 26/10/2016 20:11, Ike Naar wrote:
> On 2016-10-26, BartC <bc@freeuk.com> wrote:

>> If, however, you go through this on paper, striking through * followed
>> by &, or & followed by * with a pencil, and repeating, you end up with
>> just 'p' in all cases. And p doesn't need to be a pointer.
>>
>> On paper.
>
> This all seems to be a non-issue.  When writing code, one doesn't
> concatenate tokens at random, one writes with a purpose. What would
> be the purpose of writing '* * * & & & p' instead of 'p' ?

Macros can mean not all those tokens are visible in one place.

> Let me give you a similar example: unary minuses cancel out,
> so, for, say, double x, -(-x) and x denote the same value.
> Yet one can write 'x = 4.2;' but not '-(-x) = 4.2;'.
> So '-(-x)' and 'x' are not always interchangable, although unary minuses
> cancel out.
> Do you think this is a problem?

& and - are quite different. I wouldn't know where to start in 
explaining how.

But ***& & &p would be legal on the left of an assignment, unchanged and 
without reduction, if it was legal on the right side of it. while - -x 
wouldn't be legal on the left as it stands.

Perhaps if there was a construct in C such as IGNORENEXTOP then it could 
possibly work in a way to make the following legal:

   IGNORENEXTOP -x = 4.2;

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#95314

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-10-25 18:56 -0400
Message-ID<1b17c582-7131-4481-d83b-bb57e936a170@verizon.net>
In reply to#95250
BartC <bc@freeuk.com> writes:
[...]
> The 3000 from *pointer and the 3000 from &**pointer are the same value
> and the same type. Neither are the actual stored 3000, but a copy of
> it used as a transient rvalue existing somewhere in the workspace of
> the computer (registers, stack etc).
>
> One of these however can have & added in front, and the other can't.
>
> Why? Because *pointer is apparently an Lvalue, but &**pointer
> isn't. And why isn't it? Because it is Written. Not really very
> convincing...

Why isn't it convincing? It was written by the people officially 
responsible for defining what the language is. You might not like the 
way that they defined it, for any number of reasons, either valid or 
invalid. But you can't say that they're wrong - what they say defines 
what "right" means with respect to the C language.

Those statements are very general - let me be more specific. The 
committee explicitly decided to specify that the result of applying &* 
to an expression has the same value as that expression, but is not an 
lvalue. They had their reasons for doing so, and I think I understand 
those reasons, and agree with them. You're free to think it was a bad 
decision. You're free to define your own language where a different 
decision was made. However, if, while nominally discussing the language 
defined by that standard, you decide to say that &**pointer is an 
lvalue, you're simply wrong, by reason of ignoring a very explicit 
statement to the contrary that is part of the language definition.

A key point to keep in mind: with the standard as currently written, the 
fact that &*E is not an lvalue is explicitly stated in a part of 
6.5.3.2p3 that describes the near-cancellation of &*. That wording was 
added to resolve DR 076, which was about the fact that &*E had undefined 
behavior in C90, if *E had undefined behavior. The new wording gave such 
code defined behavior. However, you shouldn't be distracted by that 
fact. The issue that's bothering you has nothing to do with DR 076 or 
the changes that were made to resolve it.

In C90, if *E had defined behavior, then &*E was also NOT an lvalue, for 
one simple reason: the standard didn't say that it was an lvalue. The 
wording that was added in C99 merely preserved that feature, and 
extended it to cover the case where *E had undefined behavior.

> Actually I find your statements as to what is and what isn't an Lvalue
> confusing. I originally had LVALUE/NOT LVALUE above the other way
> around before I looked again at your posts.

The standard's definition of an lvalue is "an expression (with an object 
type other than void) that potentially designates an object" 
(6.3.2.1p1). There's only a few cases in the standard where something is 
explicitly said to designate an object:

     6.5.1p2: identifiers of objects,
     6.5.2.1p2: subscripted arrays
     6.5.2.3p3: structure_lvalue.member expressions
            p4: strct_ptr->member expressions
     6.5.3.2p3: dereferencing a pointer to an object type

However, in several other cases, that definition works backwards: when 
it says that a given kind of expression is an lvalue, what that means is 
that expressions of that kind potentially designate objects.

     6.5.1p4: string literals
          p5: parenthesized lvalues
     6.5.1.1p4: _Generic expressions where the result expression is an 
lvalue.
     6.5.2.5p4: Compound literals

No other kind of expression is ever an lvalue.

> I've always thought passing a writeable Lvalue to functions often
> involved adding in a & to an expression. Now you say I have to leave
> out the & to get the Lvalue!

>> Similarly, given:
>>     int n = 25;
>> the expressions `n` and `25` yield the same value and the same type, but
>> only one of them designates an object.
>
> We're talking about things that might be reasonably be expected to
> have addresses; not numeric literals which usually don't.

That's rather the key point. The only things in C which have addresses 
are objects. If your expectations say otherwise, they need correcting if 
you wish to correctly understand how C works. Expressions have values, 
but those values need not be stored in objects (even if they are the 
same as other values that are stored in objects). The only expressions 
that have associated objects are those that are explicitly described by 
the standard as being lvalues. Both &n and 25 are expressions that have 
no corresponding object where the value of that expression is stored. 
The fact that this is also true of &**pointer is just a matter of 
consistency.

The committee decided that, like most other kinds of C expressions, 
unary & expressions should not be lvalues; they didn't make an exception 
for &*E where E is itself an lvalue. They were not innovating when they 
made that decision - they were merely defining more precisely the 
meaning of the language that was, before the C standard was approved, 
less precisely defined by the "C Programming Language" by K&R. They 
apparently didn't even consider &*E where *E has undefined behavior 
until DR 076 was brought up, and when they did, they decided to handle 
it consistently with the way it was handled in the case where *E has 
defined behavior.

>> Finally, I would seriously appreciate an answer to the following.
>> Exactly what problem do you have with all this?  Do you (a) not believe
>> me when I tell you what the standard actually says, or (b) not accept
>> that the standard *means* what it says, or (c) simply dislike what the
>> standard says?

So, are you going for a), b) or c)?

[toc] | [prev] | [next] | [standalone]


#95315

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-10-25 19:12 -0400
Message-ID<806427f4-6ad9-a3e3-54d7-01a5f0dd647c@verizon.net>
In reply to#95314
On 10/25/2016 06:56 PM, James R. Kuyper wrote:
...
> That's rather the key point. The only things in C which have addresses
> are objects

(and functions, but function addresses aren't relevant to this discussion).

[toc] | [prev] | [next] | [standalone]


#95317

FromKeith Thompson <kst-u@mib.org>
Date2016-10-25 16:31 -0700
Message-ID<ln8ttc80qt.fsf@kst-u.example.com>
In reply to#95314
"James R. Kuyper" <jameskuyper@verizon.net> writes:
[...]
> Why isn't it convincing? It was written by the people officially
> responsible for defining what the language is. You might not like the
> way that they defined it, for any number of reasons, either valid or
> invalid. But you can't say that they're wrong - what they say defines
> what "right" means with respect to the C language.
[...]

Mostly.  The standard can be wrong when it's internally inconsistent, or
when it clearly fails to express the intent of its authors.  See, for
example, the current definition of "expression" (which, if taken
literally, implies that 42 is not an expression), and the C90 and C99
definitions of "lvalue" (both of which required corrections in later
editions).

Of course neither of those applies in the cases we're discussing.  The
question of whether &whatever is an lvalue has a single consistent and
deliberate answer: No.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#95244

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-10-24 21:36 +0100
Message-ID<87y41d32o2.fsf@bsb.me.uk>
In reply to#95236
BartC <bc@freeuk.com> writes:

> On 24/10/2016 17:52, Keith Thompson wrote:
>> BartC <bc@freeuk.com> writes:
>
>>> And yes I can see this being used, even if it's just to illustrate an
>>> example like this (you'll need to imagine the spaces between &s):
>>>
>>>   int **pointer;
>>>
>>>       **pointer;     // 3 net derefs (one is always implicit with
>>>                      // variables in HLLs); result: int
>>>      &**pointer;     // 2 net derefs; int*   ( *pointer)
>>>     &&**pointer;     // 1 net deref;  int**  (  pointer)
>>>    &&&**pointer;     // 0 net derefs; int*** ( &pointer)
>>>   &&&&**pointer;     // -1 net derefs: error (&&pointer)
>>
>> So the only reason you can think of to use those constructs is to
>> illustrate them?  That's hardly a good reason to add them to the
>> language.
>>
>> The unary & operator yields the address of its operand.
>
> What does that mean? And how does it work with &**pointer?

&**pointer is like *pointer _except that it's not a lvalue_.  This is
exactly what Keith said but for some reason you split his remark into
two so I need to repeat the point here.

> Because **pointer would do a double dereference to get to the
> operand. Are you saying now that the & operator effectively cancels
> that second dereference?

In &**pointer there is only one dereference operation.  Neither the &
nor the left-most * are evaluated.

> If so, then & is behaving just as I suggested: removing a dereference,
> while * adds one. (Rather than only giving the address of a named
> operand with no intervening * ops.)

You can't explain & and * in those broad terms and get all the corner
cases right.  The devil is in the detail.

> Then there is no reason why & & can't remove both dereferences.

Well no, there isn't -- it's a constraint violation so it could do
anything at all.  I'm not just being facetious -- I don't really know
what you are asking here.  Are you asking why the result of & is not an
lvalue, or just why the "& cancels */[]" rule was not defined to apply
to further levels.

>>   The resulting
>> expression is not an lvalue, so another unary & cannot be applied to it.
>
> Why is **pointer an lvalue but not *pointer?

As written, they are both lvalues, but the rules of C mean that
&**pointer is not identical to *pointer -- the latter is an lvalue and
the former isn't.

There are other ways in which &*E is not identical to E.  For example,
if E has array type, &*E will have pointer type.

> **pointer is an an rvalue that can have & in front to yield the
> equivalent of *pointer.
>
> *pointer is an rvalue that can have & in front to yield the equivalent
> of pointer.
>
> But you can't have **pointer as an rvalue that can have & & in front
> to yield the equivalent of pointer? That is, with the first & yielding
> *pointer, and the second 'pointer'.

Yup.

Could have been defined otherwise.  One option that might have satisfied
you is simply to extend the "& cancels * or []" rules to more levels.
That makes the rule fussy for very little gain since the need for
expressions of the form & &**p must be insignificant.  The second option
would have been to say that the result of & is an lvalue.  The trouble
with that is what object will it designate?  In the case of & &**p there
is an obvious choice, but not in & &i where i is declared int, say.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#95293

FromBartC <bc@freeuk.com>
Date2016-10-25 16:54 +0100
Message-ID<nunv6s$vff$1@dont-email.me>
In reply to#95244
On 24/10/2016 21:36, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:

>> But you can't have **pointer as an rvalue that can have & & in front
>> to yield the equivalent of pointer? That is, with the first & yielding
>> *pointer, and the second 'pointer'.
>
> Yup.
>
> Could have been defined otherwise.  One option that might have satisfied
> you is simply to extend the "& cancels * or []" rules to more levels.

I'm sure not that would have been necessary. Once any &* cancel out, the 
two disappear out of existence, turning '& &* *pointer' into '&*pointer' 
and then you start again, ending up with 'pointer'.

& is different from other operators that apply some function to their 
operands; the purpose of & is to /stop/ a function being applied! (A 
dereference), so neither & nor * applied to the same term can be 
considered in isolation. So in this example:

   int a;

   &*a;

the &* ought to cancel leaving just the legal 'a;'. But instead an error 
is reported about being unable to apply * to a. Presumably this check is 
done before it realises that * is eliminated by the & so that the * 
would never be applied anyway.

> That makes the rule fussy

The rule can be very simple: any adjacent &* or *& just disappear. But 
applied recursively. You should end up with 0 or 1 & (see below), or 0 
or more *.

  for very little gain since the need for
> expressions of the form & &**p must be insignificant.  The second option
> would have been to say that the result of & is an lvalue.  The trouble
> with that is what object will it designate?  In the case of & &**p there
> is an obvious choice, but not in & &i where i is declared int, say.

There is one deref associated with i (where its address is used to fetch 
its value), so two & in front would be an error.

The net number of & or * must be compatible with the type of the 
expression they are applied to. But I can't see a net number of two or 
more & being compatible with any type. So & & must be followed in the 
source by at least one *.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#95302

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-10-25 19:09 +0100
Message-ID<8760og2td1.fsf@bsb.me.uk>
In reply to#95293
BartC <bc@freeuk.com> writes:

> On 24/10/2016 21:36, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
>
>>> But you can't have **pointer as an rvalue that can have & & in front
>>> to yield the equivalent of pointer? That is, with the first & yielding
>>> *pointer, and the second 'pointer'.
>>
>> Yup.
>>
>> Could have been defined otherwise.  One option that might have satisfied
>> you is simply to extend the "& cancels * or []" rules to more levels.
>
> I'm sure not that would have been necessary.

Eh?  It's currently a constraint violation.  A change in the rules is
needed.

> Once any &* cancel out,
> the two disappear out of existence, turning '& &* *pointer' into
> '&*pointer' and then you start again, ending up with 'pointer'.

Yes, that's the gist of the rule change that would be necessary,

<snip>
>> That makes the rule fussy
>
> The rule can be very simple: any adjacent &* or *& just disappear. But
> applied recursively. You should end up with 0 or 1 & (see below), or 0
> or more *.

The rule can be very simple because you don't have to write it and make
it work!  If you want, have to go at re-writing the standard's rules
about *, []s and &.  Maybe it's simpler to do that I think -- I am open
to being persuaded.  You should probably ensure that no conforming
programs change their meaning, something that your wording above does
not manage.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#95237

Fromsupercat@casperkitty.com
Date2016-10-24 11:33 -0700
Message-ID<2cbb3b2a-06b9-4edb-b8a0-956fdd120eb4@googlegroups.com>
In reply to#95234
On Monday, October 24, 2016 at 11:52:05 AM UTC-5, Keith Thompson wrote:
> So the only reason you can think of to use those constructs is to
> illustrate them?  That's hardly a good reason to add them to the
> language.

Especially on implementations where all pointers have the same representation
and are alias-compatible with void*, it would be helpful to have a means by
which a macro that wraps a function call could ensure that it is given a
double-indirect pointer to some kind of object.  If the final target type
were required to be something other than "void", such a macro could perhaps
use:

    foo(sizeof(**(theHandle)) >= 0 ? (void**)(theHandle) : 0));

Since sizeof would not evaluate its operand, that would only cause theHandle
to be evaluated once.  I can't think of any other way, though, to write a
macro which would cast its argument to void** in the event that it was any
kind of double-indirect pointer, but would squawk if it were anything else.

[toc] | [prev] | [next] | [standalone]


#95240

FromKeith Thompson <kst-u@mib.org>
Date2016-10-24 12:22 -0700
Message-ID<ln1sz5blh8.fsf@kst-u.example.com>
In reply to#95237
supercat@casperkitty.com writes:
> On Monday, October 24, 2016 at 11:52:05 AM UTC-5, Keith Thompson wrote:
>> So the only reason you can think of to use those constructs is to
>> illustrate them?  That's hardly a good reason to add them to the
>> language.
>
> Especially on implementations where all pointers have the same representation
> and are alias-compatible with void*, it would be helpful to have a means by
> which a macro that wraps a function call could ensure that it is given a
> double-indirect pointer to some kind of object.  If the final target type
> were required to be something other than "void", such a macro could perhaps
> use:
>
>     foo(sizeof(**(theHandle)) >= 0 ? (void**)(theHandle) : 0));
>
> Since sizeof would not evaluate its operand, that would only cause theHandle
> to be evaluated once.  I can't think of any other way, though, to write a
> macro which would cast its argument to void** in the event that it was any
> kind of double-indirect pointer, but would squawk if it were anything else.

How is that relevant?  BartC is talking about constructs that are not
valid in C.  

(Of course void** is not a generic pointer-to-pointer type.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#95223

FromJames Kuyper <jameskuyper@verizon.net>
Date2016-10-24 10:23 -0400
Message-ID<nul5fs$kr4$1@dont-email.me>
In reply to#95217
BartC <bc@freeuk.com> writes:
> On 23/10/2016 18:58, James R. Kuyper wrote:
>> On 10/23/2016 01:35 PM, asetofsymbols@gmail.com wrote:
>>> I mean int *pointer, ***p;
>>> p=&(&pointer);
>>> What does it point p to?
>>
>> The parentheses are redundant, it's equivalent to & &pointer, which, as
>> I've already said, is a constraint violation. Since &pointer is not an
>> lvalue, it does not designate an object, violating 6.5.3.2p1.
>>
>> Let me expand on that explanation. &pointer is a pointer value which
>> points at the pointer object named 'pointer'. This value does not have a
>> corresponding C object that it need be stored in. That's why it's not an
>> lvalue.
[snip]
> Why not just say that & &pointer is illegal?

Because the standard uses the word "illegal" in just one footnote, as
part of the expression "illegal instruction" - it does not use it to
describe things like this. That term has connotations involving
enforcement that just don't apply to the C language. "Constraint
violation" is more specific, and precisely correct. In particular, since
it is only a constraint violation, and not illegal, it's perfectly
feasible for an implementation to support it as an extension, as I
pointed out in the part that you cut.

I added an explanation of why 6.3.5.2p1 applies, because my earlier
message on another branch of this thread already mentioned 6.3.5.2p1,
Yet asetofsymbols responded on this branch in a way that suggests he
didn't understand the how that citation was relevant - possibly he had
not bothered reading it.

> It is as meaningful as &25 (and I doubt many implementations will set up 
> a storage location containing 25 and return a pointer to that).

In the unlikely event that an implementation provided an extension
allowing & &pointer, I could easily imagine that extension being allowed
for any object-less value, including 25.

[toc] | [prev] | [next] | [standalone]


#95184

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-10-23 12:31 -0400
Message-ID<474285ad-2188-c768-8faf-a822a27681b0@verizon.net>
In reply to#95168
On 10/23/2016 11:11 AM, asetofsymbols@gmail.com wrote:
> If i have
> int buffer[10], *pointer;
>
> Where point to &buffer? Where point &&pointer? Thanks

Richard has already answered the first question, and explained that 
&&pointer is a syntax error.

If you intend to ask about & &pointer, that's not much better - it's a 
constraint violation: "The operand of the unary & operator shall be 
either a function designator, the result of a [] or unary * operator, or 
an lvalue that designates an object that is not a bit-field and is not 
declared with the register storage-class specifier." (6.5.3.2p1). 
&pointer is a pointer value, but not an lvalue - there's no C object 
designated by that expression.

If you actually intended to ask about &pointer, the answer is that 
&pointer points at the object named 'pointer'.

[toc] | [prev] | [next] | [standalone]


#95185

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-10-23 17:38 +0100
Message-ID<nuip28$gmv$1@dont-email.me>
In reply to#95184
On 23/10/16 17:31, James R. Kuyper wrote:
> On 10/23/2016 11:11 AM, asetofsymbols@gmail.com wrote:
>> If i have
>> int buffer[10], *pointer;
>>
>> Where point to &buffer? Where point &&pointer? Thanks
>
> Richard has already answered the first question, and explained that
> &&pointer is a syntax error.

Not so! I was /going/ to point out that it was a syntax error, but then 
I decided instead to explain that it isn't.

;&&pointer;

is indeed a syntax error, but &&pointer need not be. For example, in:

if(x&&pointer)

it's perfectly legal.

<good stuff snipped>

> If you actually intended to ask about &pointer, the answer is that
> &pointer points at the object named 'pointer'.

Right. And it's legal, even if pointer's value is indeterminate, because 
pointer itself is not evaluated.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#95222

FromLorinczy Zsigmond <zsiga@nospam.for.me>
Date2016-10-24 14:02 +0200
Message-ID<nukt86$1sta$1@gioia.aioe.org>
In reply to#95168
gdb might help you; it can print the values also the types, eg:

(gdb) print pointer
$1 = (int *) 0xf7e363fd <__cxa_atexit+29>
(gdb) print &pointer
$2 = (int **) 0xffffce2c
(gdb) print buffer
$3 = {13238272, 1, 134513309, -12083, 47, 134518472, 134513810, 1, -12572,
   -12564}
(gdb) print &buffer
$4 = (int (*)[10]) 0xffffce04

(gdb) ptype pointer
type = int *
(gdb) ptype &pointer
type = int **
(gdb) ptype buffer
type = int [10]
(gdb) ptype &buffer
type = int (*)[10]
(gdb) ptype *buffer
type = int

[toc] | [prev] | [next] | [standalone]


#95243

FromJohn Bode <jfbode1029@gmail.com>
Date2016-10-24 13:34 -0700
Message-ID<18af52b7-526a-44a0-ba82-09f26ef40aac@googlegroups.com>
In reply to#95168
On Sunday, October 23, 2016 at 10:11:21 AM UTC-5, asetof...@gmail.com wrote:
> If i have
> int buffer[10], *pointer;
> 
> Where point to &buffer? Where point &&pointer? Thanks

&buffer evaluates to the address of the buffer array (which is the same as
the address of the first element of the array).  Given the above 
declaration, the expressions "buffer", "&buffer", and "&buffer[0]" will
all evaluate to the same location value (modulo type conversions).

&pointer evaluates to the address of the pointer variable.  &&pointer will
be parsed as "logical-AND pointer", which is perfectly legal in an 
expression like 

    if ( buffer && pointer ) { ... }

Assuming you meant something like &(&pointer), then the operation is non-
sensical -- you're trying to take the address *of an address*, which isn't
possible.  And the compiler will complain about it, since the operand of 
the & operator must be an lvalue, and the result of &pointer is not an
lvalue.  

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.lang.c


csiph-web