库重新定义 NULL

发布于 2024-08-13 02:36:24 字数 1162 浏览 4 评论 0原文

我正在使用一个重新定义 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);

编辑:好的,显式转换是有效的,但是如何转换为函数指针?

I'm working with a library that redefines NULL. It causes some problems with other parts of my program. I'm not sure what I can do about it. Any idea? My program's in C++, the library's in C.

#ifdef NULL
#undef NULL
#endif

/**
 * NULL define.
 */
#define NULL    ((void *) 0)

Oh, and it produces these errors:

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

Here's the first one:

Generic(std::string name, Json::Value *config, int type, LCDBase *lcd = NULL);

Edit: Ok, casting explicitly works, but how do I cast for a function pointer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

把回忆走一遍 2024-08-20 02:36:24

您可以在没有该定义的情况下重建库吗?这就是我首先要尝试的。 NULL 是一个非常标准的宏,应该假设在任何地方都定义了。

现在,您的问题是 C++ 不允许像 C 那样自动从 void * 转换为其他指针类型。

来自 C++ 参考

在 C++ 中,NULL 扩展为 0 或 0L。

如果这不起作用,只需在库中进行全局替换:将 NULL 替换为 LIBDEFINEDNULL 或其他内容。这样您就可以保持库代码完整并避免宏冲突。

Can you rebuild the library without that define? That's what I'd try first. NULL is a pretty standard macro, and should be assumed to be defined everywhere.

Right now, your problem is that C++ doesn't allow automatic casts from void * to other pointer types like C does.

From C++ Reference:

In C++, NULL expands either to 0 or 0L.

If that doesn't work, just do a global replace in the library: NULL to LIBDEFINEDNULL or something. That way you'll keep the library code intact and avoid the macro collision.

亣腦蒛氧 2024-08-20 02:36:24

您有权访问该库源吗?如果是这样,我认为搜索并替换他们的代码是正确的。 (用 LIBNAME_NULL 或类似的东西替换它们的 NULL。)如果这根本不是一个选项,那么我建议在代码中使用 0 而不是 NULL。

不过我很好奇:这会导致什么问题?他们没有改变 null 的值,只是改变默认的转换。

Do you have access to that libraries source? If so, I think a search and replace on their code is in order. (Replace their NULL with LIBNAME_NULL or something similar.) If that's simply not an option then I would recommend using 0 in your code instead of NULL.

I'm curious, though: What problems is that causing? They're not changing the value of null, only the default casting.

花开浅夏 2024-08-20 02:36:24

您的评论之一说您已经考虑过自己重新定义它,但您不知道将其重新定义为什么。

许多实现都会像这样定义 NULL:

#undef NULL

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif

这是因为在 C 中,将其作为 void 指针是有意义的,因为它是可以隐式转换为其他类型的指针类型。

C++ 不允许这样做(这会导致您的问题),但使用 0 而不是 NULL 可以。

我认为在所有最近的版本中,GCC 实际上会将其定义为 __null,这是一个不可移植的扩展。

One of your comments says you've considered redefining it yourself, but you don't know what to redefine it to.

A lot of implementations will define NULL like this:

#undef NULL

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif

This is because in C, it makes sense to have it as a void pointer, because it's a pointer type that can be implicitly cast to other types.

C++ doesn't allow this (which is causing your problems), but using 0 instead of NULL works.

I think in all recent versions, GCC will actually define it to __null, which is a non-portable extension.

灼疼热情 2024-08-20 02:36:24

最通用的方法是包装有问题的包含并存储恢复宏以前的定义。然而,这取决于编译器。
这就是你如何使用 VC 来做到这一点:

#pragma push_macro("NULL")
#include <offendinglib.h>
#pragma pop_macro("NULL")

或者,将宏设置为你需要的内容:

#include <offendinglib.h>
#undef NULL
#define NULL 0

The most generic approach would be to wrap up the offending includes and store and restore the macros previous definition. This, however, is compiler-dependent.
This is how you could do it with VC:

#pragma push_macro("NULL")
#include <offendinglib.h>
#pragma pop_macro("NULL")

Alternatively, set the macro to what you need it to be afterwards:

#include <offendinglib.h>
#undef NULL
#define NULL 0
花落人断肠 2024-08-20 02:36:24

是的,你只需要适当地转换:

Generic(std::string name, Json::Value *config, int type,
    LCDBase *lcd = (LCDBase *)NULL);

Yes, you do just need to cast appropriately:

Generic(std::string name, Json::Value *config, int type,
    LCDBase *lcd = (LCDBase *)NULL);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文