[Bug c++/33101] Bad C++ error on invalid code: <anonymous> has incomplete type

Keith.S.Thompson at gmail dot com gcc-bugzilla@gcc.gnu.org
Fri Mar 16 19:32:00 GMT 2012


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33101

Keith Thompson <Keith.S.Thompson at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Keith.S.Thompson at gmail
                   |                            |dot com

--- Comment #10 from Keith Thompson <Keith.S.Thompson at gmail dot com> 2012-03-16 19:26:45 UTC ---
This came up in a question on stackoverflow.com:

    http://stackoverflow.com/q/9742135/827263

I believe the code is valid. Here's a simpler test case:

    typedef void VOID;
    int main(VOID) { }

which g++ 4.5.2 rejects with the following:

    void_test.cpp:2:10: error: ‘<anonymous>’ has incomplete type
    void_test.cpp:2:14: error: invalid use of ‘VOID’

Quoting N3290, a draft of the 2011 ISO C++ standard, section 8.3.5 [dcl.fct]:

    The parameter-declaration-clause determines the arguments that can
    be specified, and their processing, when the function is called.
    [ ... ] If the parameter-declaration-clause is empty, the function
    takes no arguments. The parameter list (void) is equivalent to
    the empty parameter list. Except for this special case, void
    shall not be a parameter type (though types derived from void,
    such as void*, can).

Earlier versions of the standard have similar or identical wording.

The last sentence implies that "void" here is being used as a type
name, not as some special-case syntactic use of the keyword.  I believe
the phrase "special case" is meant to exclude declarations like

    void foo(void, int);

or 

    void bar(void param);

not to prohibit the use of a typedef.  Since a typedef creates an
*alias* for an existing type, the name "VOID" should be usable as a
replacement for "void" whenever it's used as a type name.

Note that the syntax for a parameter-declaration does not refer
specifically to the "void" keyword; rather, "void" is valid in that
context because it's a type name.

Practically speaking, the purpose of allowing "void" as a parameter
declaration is for compatibility with C.  Quoting the latest draft
of the C standard, N1570 6.7.6.3p10:

    The special case of an unnamed parameter of type void as the only
    item in the list specifies that the function has no parameters.

It refers to the *type* void, not the keyword, implying that a
typedef is acceptable in this context -- and gcc 4.5.2 accepts the
above program without complaint when compiling it as C.

I agree that the C++ standard's wording is ambiguous, and *could*
be read as requiring the keyword "void", but I believe the intent
is to permit a typedef.  (And if you want to argue that the use of
a typedef is silly, I agree completely.)

I believe that the resolution of DR 577:
    http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#577
confirms this.  The resolution, as of August, 2011, suggests changing
the wording to refer to the *type* void rather than the keyword.  
(That change doesn't appear in the N3270 draft; I don't know whether
it appears in the final ISO C++ 2011 standard.)

At the very least, since there is (unfortunately) real-world code that 
depends on this, I suggest changing it from a fatal error to a warning,
though I think removing the diagnostic altogether would be better.



More information about the Gcc-bugs mailing list