我正在使用重新定义NULL的库。它导致我的程序的其他部分出现一些问题。我不知道我能做些什么。任何的想法?我的程序是用C ++编写的,库是 C 。
#ifdef NULL
#undef NULL
#endif
/**
* NULL define.
*/
#define NULL ((void *) 0)
哦,它产生了这些错误:
Generic.h:67: error: default argument for parameter of type 'LCD::LCDBase*' has type 'void*'
Generic.cpp: In constructor 'LCD::Generic::Generic(std::string, Json::Value*, int, LCD::LCDBase*)':
Generic.cpp:44: error: invalid conversion from 'void*' to 'QObject*'
Generic.cpp:44: error: initializing argument 2 of 'LCD::LCDWrapper::LCDWrapper(LCD::LCDInterface*, QObject*)'
Generic.cpp: In member function 'void LCD::Generic::BuildLayouts()':
Generic.cpp:202: error: invalid conversion from 'void*' to 'LCD::Widget*'
Generic.cpp: In member function 'void LCD::Generic::AddWidget(std::string, unsigned int, unsigned int, std::string)':
Generic.cpp:459: error: invalid conversion from 'void*' to 'LCD::Widget*'
scons: *** [Generic.o] Error 1
这是第一个:
Generic(std::string name, Json::Value *config, int type, LCDBase *lcd = NULL);
编辑:好的,转换显式有效,但我如何为函数指针转换?
答案 0 :(得分:5)
您可以在没有定义的情况下重建库吗?这就是我先尝试的。 NULL
是一个非常标准的宏,应该假定在任何地方定义。
现在,您的问题是C ++不允许从void *
自动转换为其他指针类型,如C。
在C ++中,NULL会扩展为0或0L。
如果这不起作用,只需在库中进行全局替换:NULL
到LIBDEFINEDNULL
或其他。这样你就可以保持库代码的完整性并避免宏冲突。
答案 1 :(得分:3)
您是否可以访问该库源?如果是这样,我认为搜索和替换他们的代码是有序的。 (用LIBNAME_NULL或类似的东西替换它们的NULL。)如果那不是一个选项,那么我建议你在代码中使用0而不是NULL。
但是,我很好奇:造成了什么问题?它们不会更改null的值,只会更改默认的转换。答案 2 :(得分:3)
最通用的方法是结束有问题的包含和存储和恢复宏以前的定义。但是,这取决于编译器 这就是你用VC做到的方法:
#pragma push_macro("NULL")
#include <offendinglib.h>
#pragma pop_macro("NULL")
或者,将宏设置为您之后需要的内容:
#include <offendinglib.h>
#undef NULL
#define NULL 0
答案 3 :(得分:3)
你的一条评论说你考虑过自己重新定义它,但你不知道要将它重新定义为什么。
很多实现都会像这样定义NULL:
#undef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif
这是因为在C中,将它作为void指针是有意义的,因为它是一个可以隐式转换为其他类型的指针类型。
C ++不允许这样做(这会导致您的问题),但使用0
代替NULL
会有效。
我认为在所有最新版本中,GCC实际上会将其定义为__null
,这是一个非便携式扩展程序。
答案 4 :(得分:-1)
是的,你只需要适当地施放:
Generic(std::string name, Json::Value *config, int type,
LCDBase *lcd = (LCDBase *)NULL);