G ++ error: "<anonymous> is of incomplete type
I have to use a third-party dongle access library, which includes the "sense4.h" file with the code as follows:
#if !defined _WINDOWS_ #define WINAPI #define CONST const typedef unsigned char UCHAR; typedef unsigned short USHORT; typedef unsigned int UINT; typedef unsigned long ULONG; typedef char CHAR; typedef char TCHAR; typedef void VOID; ... #endif /* !defined _WINDOWS */ ... unsigned long WINAPI S4Startup( VOID ); unsigned long WINAPI S4Cleanup( VOID ); ...
The problem is that g ++ 4.6.1 complains about lines of code that use typedefed VOID:
sense4.h:375:9: error: '<anonymous>' has incomplete type sense4.h:376:1: error: invalid use of 'VOID {aka void}' sense4.h:383:9: error: '<anonymous>' has incomplete type sense4.h:384:1: error: invalid use of 'VOID {aka void}'
Is there anything I can do without modifying the include.h file? include so that my project compiles with g ++?
Update 1
I found out that section 18 of C ++ Standard Core Closed Issues, version 30 states:
If the parameter-declaration clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the list of empty parameters.
Is it possible to use typedef for void instead of type void in the parameter list?
Rationale: IS is already clear that this is unacceptable.
Summary: C ++ code is not valid, although there is some clarity as to whether it should be. Using void
rather than void
, or just using empty parentheses, avoids the error.
I think this is a bug in g ++.
I thought this was a bug in g ++. Now I am sure that this is not the case, although I argue that it would be better to make this a warning rather than a fatal mistake.
Usually in C ++ a function without parameters is declared with empty parentheses:
int foo();
As a concession to compatibility with C, C ++ also allows a C-style prototype, using void
to indicate that the function has no parameters (since empty parentheses mean something else in C):
int bar(void);
The g ++ interpretation seems that void
in this syntax is not an incomplete void
type; rather, he sees it as a special syntax with clear use of the keyword.
I think you will need to modify the header file in order to get g ++ to accept it.
gcc accepts it as valid C, but this is not useful if you need to #include
it from the C ++ source file β unless you write a C shell and call it from your C ++ code, which may be an acceptable workaround .
(By the way, I hate typedefs like this. What is the purpose of typedef void VOID;
;? Did the author think that void
was too confusing? I suspect it is compatible with very old C compilers that don't support the void
keyword, but this is necessary long ago.)
Here is the relevant description from the latest draft of the ISO C ++ 2011 standard (8.3.5 [dcl.fct]):
The declaration-clause parameter defines the arguments that can be specified and processed by the function call. [...] If the parameter-declaration-sentence is empty, the function accepts no arguments. The parameter list
(void)
equivalent to the empty parameter list. Except for this special case,void
will not be a parameter type (although types derived fromvoid
, such asvoid*
, may).
This means that the void
keyword in int bar(void);
refers to the void
type. Since the name typedef is a synonym for the named type, int bar(void);
must be equally legal. It would be best to use a typedef name, for example void
instead of void
, but the wording of the standard actually refers to the void
keyword, not the type.
The whole purpose of resolution (void)
is C compatibility. To add to the confusion, the 1990 ISO C standard requires the void
keyword; 1999 and 2011 standards reworded to allow the introduction of a typedef instead. Answer The C ++ Bug Report # 577 confirms that the current language requires the void
keyword and suggests a change that will allow typedef to be used - - but this change has not yet been set in any C ++ ISO standard. It will probably appear in the first technical fix for C ++ 2011 when it is published.
Thanks to another.anon.coward for finding an existing gcc error report . I added a too detailed comment, suggesting that the code is valid and that no error message should be generated - and a later comment recognizing that the code is invalid but that the warning would be more appropriate than a fatal error.
In the meantime, I suggest contacting the provider of this sense4.h
header file. If they assumed that it is #include
d only from C code, there is no real problem (except for the bad IMHO style); otherwise, they might consider using #ifdef __cplusplus
by declaring functions with (void)
in C and ()
in C ++. And you can go do it yourself. Whether g ++ should accept the code or not, with a few changes it would be valid C, valid C ++, acceptable for both gcc and g ++, and a better style.
If you read this far, and you are still awake, I am impressed.