Topic: Defect Report: 8.3.1/1, 8.3.4/1: description ignores precedence


Author: william.m.miller@gmail.com
Date: Fri, 24 Feb 2006 10:27:03 CST
Raw View
Krzysztof Zelechowski wrote:
> Uzytkownik <william.m.miller@gmail.com> napisal w wiadomosci
> news:1138217361.291010.186680@g49g2000cwa.googlegroups.com...
> > "Krzysztof Zelechowski" wrote:
> >> Thank you, your answer is comprehensive and exhaustive.  Almost
> >> everything
> >> is clear now except that did not address the issue that an array is being
> >> defined in the section "Meaning of pointers".  Perhaps the section title
> >> should be changed because a pointer is a semantic entity, not a syntactic
> >> one, and I would not look for a recipe how to declare an array in this
> >> section.
> >
> > And you will not find it there, either.  Each of the subsections of
> > 8.3 deals with a single level in the recursive tree-walk.  In your
> > example, when you are in 8.3.1, you are declaring a pointer to
> > whatever declarator was processed at the next level down in the
> > syntax tree.  In this case, it's a pointer to an array.  However,
> > 8.3.1 deals only with the "pointer" part.  The "array" part was
> > dealt with at the appropriate level of the tree by 8.3.4.
>
> No sir, it is an array of pointers.  You have put it wrong yourself.  That
> is just my point.
> In order to identify the semantics of a structure we have to traverse a
> tree.  If the root node is labeled "Meaning of X", we can be sure that
> whatever follows constitutes ultimately an X, provided that X is a semantic
> entity and not a syntactic entity.  The description T *D1 suggests that it
> is the root node and the child node is labeled D1[01].  It gives us the
> false impression that we the char *arr[01] is a pointer.  It is not.
> Conclusion: the label is misleading.  Resolution: change the label to
> "Meaning of asterisks".

You are, of course, correct that I was careless and my informal
rendering of 8.3.1 was wrong.  My apologies; I was focusing on
the fact that 8.3.1 deals only with the "pointer" part of the
declarator, not the "array" part, and I did not pay enough
attention to the rest of what I was writing.  However, I still
think that it's appropriate to have "pointer" in the title of the
section; the ultimate type is "array of pointer", and there was no
"pointer" in the English description built by the tree traversal
until it reached 8.3.1.  The assumption that what comes out of
8.3.1 must itself be a pointer, simply because the title of the
section is "Pointers," is incorrect; instead, it shouild be
understood that 8.3.1 will add a "pointer to" term to the
derived-declarator-type-list.  In this case, the
derived-declarator-type-list prior to the application of 8.3.1 is
"array of one char;" afterwards, it is "array of one pointer to char."

-- William M. (Mike) Miller
   Edison Design Group

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: krixel@qed.pl ("Krzysztof Zelechowski")
Date: Tue, 24 Jan 2006 15:58:08 GMT
Raw View
Uzytkownik <william.m.miller@gmail.com> napisal w wiadomosci
news:1136911161.022856.286780@z14g2000cwz.googlegroups.com...
> Christopher Yeleighton wrote:
>> [ Moderator's note: Forwarded to C++ committee. -sdc ]
>>
>> 1. Consider the declaration "char *arr[01]".  Take "char" for T,
>> "*arr[01]"
>> for D.
>>
>> 1.1. Take "arr[01]" for D1 to match the assumptions.  T D1 resolves to
>> "char
>> arr[01]" and the type of identifier "arr" in T D1 is "array of 1 char"
>> according to 8.3.4/1.  Therefore the type of identifier "arr" is "
>> array of 1 pointer to char".  This is counterintuitive: an array is
>> defined
>> in the section "Meaning of pointers".
>>
>> 1.2. Take "*arr" for D1. T D1 resolves to "char *arr" and the type of
>> identifier "arr" in T D1 is "pointer to char".  8.3.4/1 implies that the
>> type of identifier "arr" is "pointer to array of 1 char" and that it
>> denotes
>> an array at the same time.  Internal contradiction and contradiction to
>> the
>> deduction of 1.1.  It should be mentioned that in "D1[01]" does not match
>> "D" in this setting.
>>
>> The statement of 8.3/6: "Parentheses can alter the binding of complex
>> declarators" is meaningless because the term "binding" is undefined in
>> this
>> context.
>
> The C++ Standard describes the binding/precedence of both
> expressions and declarators via the syntactic productions.  To
> grasp how the specifications in the subsections of 8.3 are to be
> understood and applied, you have to start with the grammar of
> declarators at the beginning of clause 8.  The syntax of
> declarator is:
>
>  declarator:
>      direct-declarator
>      ptr-operator declarator
>

The problem is that 8.3.4 is not explicit that D1 must denote a direct
declarator.  Literal reading gives you the impression that D1 can be just
anything.
Chris


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: krixel@qed.pl ("Krzysztof Zelechowski")
Date: Tue, 24 Jan 2006 17:58:34 GMT
Raw View
Thank you, your answer is comprehensive and exhaustive.  Almost everything
is clear now except that did not address the issue that an array is being
defined in the section "Meaning of pointers".  Perhaps the section title
should be changed because a pointer is a semantic entity, not a syntactic
one, and I would not look for a recipe how to declare an array in this
section.
Chris

Uzytkownik <william.m.miller@gmail.com> napisal w wiadomosci
news:1136911161.022856.286780@z14g2000cwz.googlegroups.com...
> Christopher Yeleighton wrote:
>> [ Moderator's note: Forwarded to C++ committee. -sdc ]
>>
>> 1. Consider the declaration "char *arr[01]".  Take "char" for T,
>> "*arr[01]"
>> for D.
>>
>> 1.1. Take "arr[01]" for D1 to match the assumptions.  T D1 resolves to
>> "char
>> arr[01]" and the type of identifier "arr" in T D1 is "array of 1 char"
>> according to 8.3.4/1.  Therefore the type of identifier "arr" is "
>> array of 1 pointer to char".  This is counterintuitive: an array is
>> defined
>> in the section "Meaning of pointers".
>>
>> 1.2. Take "*arr" for D1. T D1 resolves to "char *arr" and the type of
>> identifier "arr" in T D1 is "pointer to char".  8.3.4/1 implies that the
>> type of identifier "arr" is "pointer to array of 1 char" and that it
>> denotes
>> an array at the same time.  Internal contradiction and contradiction to
>> the
>> deduction of 1.1.  It should be mentioned that in "D1[01]" does not match
>> "D" in this setting.
>>
>> The statement of 8.3/6: "Parentheses can alter the binding of complex
>> declarators" is meaningless because the term "binding" is undefined in
>> this
>> context.
>
> The term "binding" is used in its ordinary sense of associating
> various syntactic elements with each other during parsing, i.e.,
> turning a linear sequence of tokens into a hierarchical syntax
> tree.  For example, in expressions "*" binds more tightly, i.e., has
> a higher precedence, than "+".  Thus, in an expression like a+b*c,
> the binding is "a plus the product of b and c."  Just as in
> declarators, parentheses can change the binding, so that (a+b)*c
> means "the sum of a and b, times c."  This usage is common
> enough that I do not believe it is a defect for it not to be defined
> here.
>
> The C++ Standard describes the binding/precedence of both
> expressions and declarators via the syntactic productions.  To
> grasp how the specifications in the subsections of 8.3 are to be
> understood and applied, you have to start with the grammar of
> declarators at the beginning of clause 8.  The syntax of
> declarator is:
>
>  declarator:
>      direct-declarator
>      ptr-operator declarator
>
> The nonterminal direct-declarator is where the function and array
> declarator operators are applied.  What this means is that the
> function and array operators bind more tightly than the pointer
> operators -- that is, you only apply pointer operators to a
> declarator that is a direct-declarator, already containing the
> array or function operators.
>
>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: william.m.miller@gmail.com
Date: Wed, 25 Jan 2006 23:35:39 CST
Raw View
"Krzysztof Zelechowski" wrote:
> Thank you, your answer is comprehensive and exhaustive.  Almost everything
> is clear now except that did not address the issue that an array is being
> defined in the section "Meaning of pointers".  Perhaps the section title
> should be changed because a pointer is a semantic entity, not a syntactic
> one, and I would not look for a recipe how to declare an array in this
> section.

And you will not find it there, either.  Each of the subsections of
8.3 deals with a single level in the recursive tree-walk.  In your
example, when you are in 8.3.1, you are declaring a pointer to
whatever declarator was processed at the next level down in the
syntax tree.  In this case, it's a pointer to an array.  However,
8.3.1 deals only with the "pointer" part.  The "array" part was
dealt with at the appropriate level of the tree by 8.3.4.

You seem to be expecting each subsection of 8.3 to deal with
the entire declarator, not just one level of the tree, and that's
just not true.  To process your example, you will use _both_
8.3.1 _and_ 8.3.4; there's no concept of "array" in 8.3.1.

-- William M. (Mike) Miller
   Edison Design Group

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Krzysztof Zelechowski" <krixel@qed.pl>
Date: Fri, 27 Jan 2006 09:35:44 CST
Raw View
Uzytkownik <william.m.miller@gmail.com> napisal w wiadomosci
news:1138217361.291010.186680@g49g2000cwa.googlegroups.com...
> "Krzysztof Zelechowski" wrote:
>> Thank you, your answer is comprehensive and exhaustive.  Almost
>> everything
>> is clear now except that did not address the issue that an array is being
>> defined in the section "Meaning of pointers".  Perhaps the section title
>> should be changed because a pointer is a semantic entity, not a syntactic
>> one, and I would not look for a recipe how to declare an array in this
>> section.
>
> And you will not find it there, either.  Each of the subsections of
> 8.3 deals with a single level in the recursive tree-walk.  In your
> example, when you are in 8.3.1, you are declaring a pointer to
> whatever declarator was processed at the next level down in the
> syntax tree.  In this case, it's a pointer to an array.  However,
> 8.3.1 deals only with the "pointer" part.  The "array" part was
> dealt with at the appropriate level of the tree by 8.3.4.

No sir, it is an array of pointers.  You have put it wrong yourself.  That
is just my point.
In order to identify the semantics of a structure we have to traverse a
tree.  If the root node is labeled "Meaning of X", we can be sure that
whatever follows constitutes ultimately an X, provided that X is a semantic
entity and not a syntactic entity.  The description T *D1 suggests that it
is the root node and the child node is labeled D1[01].  It gives us the
false impression that we the char *arr[01] is a pointer.  It is not.
Conclusion: the label is misleading.  Resolution: change the label to
"Meaning of asterisks".
Chris


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Christopher Yeleighton <krixel@qed.pl>
Date: Fri, 30 Dec 2005 18:21:15 +0000 (UTC)
Raw View
[ Moderator's note: Forwarded to C++ committee. -sdc ]

1. Consider the declaration "char *arr[01]".  Take "char" for T, "*arr[01]"
for D.

1.1. Take "arr[01]" for D1 to match the assumptions.  T D1 resolves to "char
arr[01]" and the type of identifier "arr" in T D1 is "array of 1 char"
according to 8.3.4/1.  Therefore the type of identifier "arr" is "
array of 1 pointer to char".  This is counterintuitive: an array is defined
in the section "Meaning of pointers".

1.2. Take "*arr" for D1. T D1 resolves to "char *arr" and the type of
identifier "arr" in T D1 is "pointer to char".  8.3.4/1 implies that the
type of identifier "arr" is "pointer to array of 1 char" and that it denotes
an array at the same time.  Internal contradiction and contradiction to the
deduction of 1.1.  It should be mentioned that in "D1[01]" does not match
"D" in this setting.

The statement of 8.3/6: "Parentheses can alter the binding of complex
declarators" is meaningless because the term "binding" is undefined in this
context.





[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: william.m.miller@gmail.com
Date: Tue, 10 Jan 2006 11:26:55 CST
Raw View
Christopher Yeleighton wrote:
> [ Moderator's note: Forwarded to C++ committee. -sdc ]
>
> 1. Consider the declaration "char *arr[01]".  Take "char" for T, "*arr[01]"
> for D.
>
> 1.1. Take "arr[01]" for D1 to match the assumptions.  T D1 resolves to "char
> arr[01]" and the type of identifier "arr" in T D1 is "array of 1 char"
> according to 8.3.4/1.  Therefore the type of identifier "arr" is "
> array of 1 pointer to char".  This is counterintuitive: an array is defined
> in the section "Meaning of pointers".
>
> 1.2. Take "*arr" for D1. T D1 resolves to "char *arr" and the type of
> identifier "arr" in T D1 is "pointer to char".  8.3.4/1 implies that the
> type of identifier "arr" is "pointer to array of 1 char" and that it denotes
> an array at the same time.  Internal contradiction and contradiction to the
> deduction of 1.1.  It should be mentioned that in "D1[01]" does not match
> "D" in this setting.
>
> The statement of 8.3/6: "Parentheses can alter the binding of complex
> declarators" is meaningless because the term "binding" is undefined in this
> context.

The term "binding" is used in its ordinary sense of associating
various syntactic elements with each other during parsing, i.e.,
turning a linear sequence of tokens into a hierarchical syntax
tree.  For example, in expressions "*" binds more tightly, i.e., has
a higher precedence, than "+".  Thus, in an expression like a+b*c,
the binding is "a plus the product of b and c."  Just as in
declarators, parentheses can change the binding, so that (a+b)*c
means "the sum of a and b, times c."  This usage is common
enough that I do not believe it is a defect for it not to be defined
here.

The C++ Standard describes the binding/precedence of both
expressions and declarators via the syntactic productions.  To
grasp how the specifications in the subsections of 8.3 are to be
understood and applied, you have to start with the grammar of
declarators at the beginning of clause 8.  The syntax of
declarator is:

  declarator:
      direct-declarator
      ptr-operator declarator

The nonterminal direct-declarator is where the function and array
declarator operators are applied.  What this means is that the
function and array operators bind more tightly than the pointer
operators -- that is, you only apply pointer operators to a
declarator that is a direct-declarator, already containing the
array or function operators.

The parse tree for your example is as follows (omitting a few
empty productions):

          declarator
         /          \
        /            \
       /              \
     '*'      direct-declarator
             /                 \
            /                   \
           /                     \
  direct-declarator          '[' '01' ']'
          |
          |
          |
        'arr'

Note that your 1.2, "*arr", is not a possible choice for an
intermediate declarator -- the syntax does not allow it.  You can
only apply a "*" to a complete direct-declarator, not to the left
subtree of one.

The approach for defining declarator operators in 8.3 and its
subsections is recursive: you do a recursive tree walk of the
syntax tree until you get down to the declarator-id and then
annotate the description as each level of recursion returns.

8.3p5 tells you that "char arr" means that arr is of type char.

The next level up from "arr" is "arr[01]".  8.3.4p1 says, "In a
declaration T D where D has the form

  D1 [ constant-expression-opt ]

and the type of the identifier in the declaration T D1 is
'derived-declarator-type-list T," then the type of the identifier of
D is... 'derived-declarator-type-list array of N T.'"

In this case, D (from the syntax tree at this level) is "arr[01]",
D1 is just "arr", and derived-declarator-type-list is empty.  The
type of arr at this level is "array of 1 char."

The next level up the tree is "*arr[01]".  8.3.1p1 says, "In a
declaration T D where D has the form

  * cv-qualifier-seq-opt D1

and the type of the identifier in the declaration T D1 is
'derived-declarator-type-list T,' then the type of the identifier
of D is 'derived-declarator-type-list cv-qualifier-seq pointer to T.'"

Here, D is "*arr[01]", D1 is "arr[01]", and
derived-declarator-type-list is (from the previous level) "array of
1".  Substituting, we get the type of arr at this level as "array of
1 pointer to char."  And we're done, because we've arrived at the
top of the tree.

The note about "Parentheses do not alter the type of the embedded
declarator-id, but they can alter the binding of complex
declarators" is just recognition of the syntactic production

  direct-declarator:
      ( declarator )

As I mentioned above, the array and function declarator operators
apply only to direct-declarators and the pointer operators apply only
to declarators.  With this little bit of recursion, you can override
that restriction.  Consider what happens when you modify your
example to read "char (*arr)[01]".  Now the parse tree is:

                   declarator
                        |
                        |
                        |
               direct-declarator
              /                 \
             /                   \
            /                     \
   direct-declarator          '[' '01' ']'
           |
           |
           |
   '(' declarator ')'
      /          \
     /            \
    /              \
  '*'      direct-declarator
                   |
                   |
                   |
                 'arr'

Again, we start at the bottom and work our way up:

8.3p5: arr is of type char.

8.3.1: D is "*arr", D1 is "arr", derived-declarator-type-list is
empty; => "pointer to char."

8.3p6: D is "(*arr)", D1 is "*arr", derived-declarator-type-list is
"pointer to"; => "pointer to char" (same as D1).

8.3.4: D is "(*arr)[01]", D1 is "*arr", derived-declarator-type-list is
"pointer to"; => "pointer to array of 1 char."

There's no ambiguity or defect in 8.3 and subsections, but it does
require reading them in conjunction with the grammar given at the
beginning of clause 8.

-- William M. (Mike) Miller
   Edison Design Group

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]