ezp*_*sso 6 gcc typedef g++ void
我被迫使用第三方加密狗访问库,提供包含文件'sense4.h',其代码如下:
#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
);
...
Run Code Online (Sandbox Code Playgroud)
问题是g ++ 4.6.1抱怨使用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}’
Run Code Online (Sandbox Code Playgroud)
如果不改变'sense.h'包含文件以使我的项目用g ++编译,我能做些什么吗?
我发现C++标准核心语言已关闭问题第30修订版第18节规定:
如果parameter-declaration-clause为空,则该函数不带参数.参数列表(void)等效于空参数列表.
是否可以使用typedef为void而不是参数列表中的void类型?
理由:IS已经很清楚,这是不允许的.
快速摘要:代码是无效的C++,虽然它是否应该是一些缺乏明确性.使用void而不是VOID仅使用空括号将避免错误.
我认为这是g ++中的一个错误.
我认为这是g ++中的一个错误.我现在确信它不是,尽管我认为最好将此作为警告而不是致命的错误.
通常在C++中,没有参数的函数用空括号声明:
int foo();
Run Code Online (Sandbox Code Playgroud)
作为对C兼容性的让步,C++还允许使用C风格的原型,void用于指示该函数没有参数(因为空括号表示C中的其他内容):
int bar(void);
Run Code Online (Sandbox Code Playgroud)
g ++的解释似乎是void这里的语法中没有提到不完整的类型 void ; 相反,它将它视为一种特殊的语法,并使用了关键字.
我认为你需要修改头文件才能让g ++接受它.
gcc接受它作为有效的C,但如果您需要#include从C++源文件中获取它,则无效- 除非您编写C包装并从C++代码调用它,这可能是一种可接受的解决方法.
(顺便说一下,我讨厌这样的 typedef.目的是typedef void VOID;什么?作者认为void是不是太混乱了?我怀疑这是为了与那些不支持该void关键字的旧C编译器兼容,但对此的需求早已过去.)
以下是ISO C++ 2011标准(8.3.5 [dcl.fct])的最新草案中的相关描述:
的参数声明子句确定可指定的参数,以及它们的处理中,当调用该函数时.[...]如果parameter-declaration-clause为空,则该函数不带参数.参数列表
(void)等同于空参数列表.除了这种特殊情况,void不应该是参数类型(尽管类型派生自void,例如void*,可以).
这意味着void关键字in int bar(void);确实引用了类型void. 由于typedef名称是命名类型的同义词,因此 对于类似于int bar(VOID);应该是同等合法的.VOID被接受的typedef名称来说,最有意义的是void,但标准的措辞实际上是指关键字void,而不是类型.
允许的全部目的(void)是C兼容性.只是为了增加混淆,1990 ISO C标准需要void关键字; 1999和2011 C标准改变了措辞,允许使用typedef.对C++缺陷报告#577的响应确认当前的措辞需要void关键字,并提出允许typedef的更改 - 但该更改尚未在任何ISO C++标准中.它可能会出现在C++ 2011的第一个技术勘误表中.
感谢another.anon.coward查找现有的gcc错误报告.我添加了一个过于冗长的注释,表明代码是有效的,不应该生成错误消息 - 以及稍后的注释,承认代码无效,但是警告比致命错误更合适.
在此期间,我建议您联系此sense4.h头文件的提供者.如果他们#include只想从C代码中获取它,那么它就没有真正的问题(除了恕我直言的糟糕风格); 否则,他们可能会考虑使用C语言和C++ #ifdef __cplusplus语句来声明函数.你可以继续自己做出改变.无论g ++是否应该接受代码,只需进行一些更改,它就是有效的C,有效的C++,gcc和g ++都可以接受,以及更好的风格.(void)()
如果你已经阅读了这篇文章并且你仍然清醒,我印象深刻.
| 归档时间: |
|
| 查看次数: |
6903 次 |
| 最近记录: |