This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-10-26


340. Unclear wording in disambiguation section

Section: 9.3.3  [dcl.ambig.res]     Status: NAD     Submitter: Bart v Ingen Schenau     Date: 27 Feb 2002

Consider the following program:

  struct Point
  {
    Point(int){}
  };
  struct Lattice
  {
    Lattice(Point, Point, int){}
  };
  int main(void)
  {
    int a, b;
    Lattice latt(Point(a), Point(b), 3);   /* Line X */
  }

The problem concerns the line marked /* Line X */, which is an ambiguous declarations for either an object or a function. The clause that governs this ambiguity is 9.3.3 [dcl.ambig.res] paragraph 1, and reads:

The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in 8.9 [stmt.ambig] can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in 8.9 [stmt.ambig], the resolution is to consider any construct that could possibly be a declaration a declaration. [Note: a declaration can be explicitly disambiguated by a nonfunction-style cast, by a = to indicate initialization or by removing the redundant parentheses around the parameter name. ]

Based on this clause there are two possible interpretations of the declaration in line X:

  1. The declaration of latt declares a function with a return value of the type Lattice and taking three arguments. The type of the first two arguments is Point and each of these arguments is followed by a parameter name in redundant parentheses. The type of the third argument can not be determined, because it is a literal. This will result in a syntax error.
  2. The declaration of latt declares an object, because the other option (a function declaration) would result in a syntax error.

Note that the last sentence before the "[Note:" is not much help, because both options are declarations.

Steve Adamczyk: a number of people replied to this posting on comp.std.c++ saying that they did not see a problem. The original poster replied:

I can't do anything but agree with your argumentation. So there is only one correct interpretation of 9.3.3 [dcl.ambig.res] paragraph 1, but I have to say that with some rewording, the clause can be made a lot clearer, like stating explicitly that the entire declaration must be taken into account and that function declarations are preferred over object declarations.

I would like to suggest the following as replacement for the current 9.3.3 [dcl.ambig.res] paragraph 1:

The ambiguity arising from the similarity between a functionstyle cast and a declaration mentioned in 8.9 [stmt.ambig] can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. The resolution is to consider any construct that could possibly be a function declaration a function declaration. [Note: To disambiguate, the whole declaration might have to be examined to determine if it is an object or a function declaration.] [Note: a declaration can be explicitly disambiguated by a nonfunction-style cast, by a = to indicate initialization or by removing the redundant parentheses around the parameter name. ]

Notes from the 4/02 meeting:

The working group felt that the current wording is clear enough.