Re: help with 'left-right' cdecl rule



On Mon, 13 Feb 2006 17:12:16 -0800, Old Wolf wrote:

jonsmallberries@xxxxxxxxx wrote:
In the FAQ they said to read from inside out. So yeah, this does make
sense foo is a const pointer to int.

This "const int * foo" also makes sense, foo is a pointer to a const
int.

But, "int const * foo" is just lame. I checked just for clarity's sake
to see if this is the same in C++ (it is) and the site had this to say.


It is the "const int * foo" version which is lame. Reading from insde out,
as you suggest:

const int * foo foo is a pointer to an int constant int const * foo
foo is a pointer to a constant int

"Basically 'const' applies to whatever is on its immediate left other
than if there is nothing there in which case it applies to whatever is
its immediate right)." Can we say confusing?

The "int const * foo" version obeys the first part of this rule, the
confusing exception is necessary to cover the case of "const int * foo" .

I find it easier not to think in terms of rules with exceptions. C type
declarations are structred like nested expressions. The various tokens
int, cont, *, [], () and so on behave like "type operators" applied to the
thing being declared. As a result, declarations need to be read "inside
out" starting from the name. You always read to the right first if you
can (function brakets and array brakets) and then to the left where you
will find * and const and volatile and so on.

Because the type may be nested, you may have to finish off an inner
bracketed part before continuing outside -- again reading to the right if
there is anything there before going left.

You can work out an exact list of what to say when you hit a particular
tokens (<OT>very useful for C++ pointer to member function types that can
be hard to read at first</OT>) but the main parts are:

<name> -- say: "name is a"
( -- say: "function taking" then read the declarators for the
formal parameters (say "unknown" if there are none)
) -- say: "and returning a"
[ -- say: "array of"
] -- say: nothing
* -- say: "pointer to a"
const -- say: "constant"
int, etc -- say: "int" or "character" or whatever
<num> -- read out the number

If you hit a ")" without having read out the opening "(" then you are
inside a nested type and you have to finish reading it (by going left)
before jumping out. When you hit the matching "(" you just continue as if
the barcketed part were no longer there (i.e. start reading to the right
again).

As a result, you clear up "int const *x" and "const int *x" for free
since they read as "x is a pointer to a constant int" and "x is a pointer
to an int constant" which have the same natural meaning in English.

It really pays off with pointer to function types:

int const *const (*f)(void);

Goes: "f is a" -- can't go right because of the ")" so we are in a nested
type and need to finish it -- "pointer to a" -- we can now remove the
nested part and keep going -- "function taking void and
returning a constant pointer to constant int".

It is simpler to do that is sounds, honest! (The hardest part is spotting
where the name should be when you are reading the type in a cast or a
nameless formal paramater -- these look just like a declarations but with
the name missing).

--
Ben.

.



Relevant Pages

  • Re: Funky function
    ... >> It makes it possible to call this member function on a const object ... >> object may or may not be const). ... int Data; ... in the next line you try to call a function foo on MyData. ...
    (comp.lang.cpp)
  • Re: Question about array declarators
    ... I found that the type of this declarator was "array of pointer to ... const int". ... type with "const int". ... The qualifiers on the type pointed at by fooare "const", the qualifiers on the type pointed at by &i are "". ...
    (comp.lang.c)
  • Re: Virtual function and multiple inheritance
    ... virtual int func(); ... class Derived: Foo, Goo { ... Here pF is a pointer to an object with the same memory layout as a Foo and pG is a pointer to an object with the same memory layout as a Goo. ...
    (microsoft.public.vc.language)
  • Re: Whats the deal with const?
    ... specify the const part. ... The definition of a function parameter as "const char *x" defines that ... argument as a pointer to one or more constant characters. ... int some_func ...
    (comp.lang.c)
  • Re: FAQ 13.8, comparing strings
    ... int main{ ... Neither of those forms is compatible with const void *. ... The two type forms are equivalent, and both mean "pointer to const T". ...
    (comp.lang.c)