如何使用 #define 定义 NULL
我想在我的程序中重新定义 NULL,例如
#define MYNULL ((void*)0)
但此定义在以下语句中不起作用:
char *ch = MYNULL;
<块引用>错误:无法从 void* 转换为 char *
定义 NULL 的最佳方法是什么?
I want to redefine NULL in my program such as
#define MYNULL ((void*)0)
But this definition is not working in the following statement:
char *ch = MYNULL;
Error : can not convert from void* to char *
What would be the best way to define NULL?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是最安全的,我认为没有理由这样做,但如果你真的想这样做,那就继续吧。
C 和 C++ 分别是这样做的:
一般来说,为 NULL 定义 0 是一个坏习惯,你实际上希望它成为语言的一部分。 C++0x 解决了这个问题。
这是 Bjarne Stroustrup 必须对此说的:
is the safest, I see no reason in doing so but if you really want to, go ahead.
Here's how C and C++ do it respectively:
Generally speaking, defining 0 for NULL is a bad habit, you actually want it to be part of the language. C++0x adresses this.
This is what Bjarne Stroustrup has to say on this:
都适用于它们。
will work in both of them.
从你应该的地方获取 NULL 到底有什么问题?即,
或者
正如 @Johannes Rudolph 的答案中提到的,面对诸如
之类的事情,你所做的任何欺骗都不太可能在未来得到证明。 nullptr
等。编辑:虽然 stdlib (和许多其他)被强制包含
NULL
,但 stddef 是最规范的头文件 [并且已经存在了几十年了]。PS 一般来说,除非你有充分的理由,否则参与这种骗局是一个坏主意。你没有扩展让你觉得有必要这样做的想法。如果您可以添加一些细节,可能会得到更好的答案。回答这个问题的其他人也应该在他们的答案中指出这一点,但我想 FGITW 是最好的:D
编辑 2:正如@Yossarian 所指出的:这样做的唯一理由是如果没有在 中定义 NULL系统中其他地方的适当的与语言无关的形式。没有标头的裸编译器和/或如果您从头开始编写自己的自定义标准库就是这种情况的示例。 (在这种简单的情况下,我会选择 @lilburne 的答案(请确保尽可能使用
0
))What exactly is the problem with getting your NULL from where you're supposed to?, i.e.,
or
as alluded to in @Johannes Rudolph's answer, any trickery you do is not likely be very future proof in the face of things like
nullptr
etc.EDIT: while stdlib (and many others) are mandated to include a
NULL
, stddef is the most canonical header [and has been for decades].PS In general, it's just a bad idea to get involved in this sort of trickery unless you have a really good reason. You didnt expand on the thinking that led you to feeling the need to do this. If you could add some detail on that, it's likely to lead to better answers. Other people answering the question should have pointed this out in their answers too, but I guess does FGITW as FGITW does best :D
EDIT 2: As pointed out by @Yossarian: The single justification for doing this is if there isnt a NULL defined in an appropriately language-agnostic form elsewhere in your system. Naked compilers with no headers and/or if you're writing your own custom standard library from scratch are examples of such a circumstance. (In such a bare-bones scenario, I'd go with @lilburne's answer (be sure to use
0
as much as possible))将在 C++ 中工作
will work in C++
不要这样做。
没有任何规定 NULL 必须为零值,它是特定于实现的。它可以是代表结束的值内存中的某些特殊位置,甚至是不存在任何值的对象。这样做非常危险,可能会破坏可移植性,并且肯定会破坏代码感知编辑器。它不会给你买任何东西,相信你的图书馆的定义。
编辑:埃文是正确的!代码本身会说零,在幕后编译器可以通过实现特定细节做它想做的事情。谢谢埃文!
Don't do this.
There is nothing that says that NULL has to be the value zero, it's implementation specific.It could be a value that represents the end of memory, some special place in memory, or even an object that represents no value exists.Doing this is very dangerous, may break portability, and will most certainly screw with code-aware editors. It isn't buying you anything, trust your library's definition.
EDIT: Evan is correct! The code itself will say zero, under the hood the compiler can do what it wants with implementation specific details. Thanks Evan!
我认为任何不知道在 C/C++ 中将指针设置为 0 与将其设置为 NULL、nullptr 或任何其他等效项的人都不应弄乱代码。 之间的可读性差异
和
很小。当涉及到表达式时,表格的
可读性并不比
I think that anyone that doesn't know that setting a pointer in C/C++ to 0 is the same as setting it to NULL, nullptr, or any other equivalent shouldn't be messing with code. The difference in readability between
and
is minimal. When it comes to expressions the forms
are no more readable than
与某些人在这里所说的相反,0 是 C 中 NULL 的完全有效的定义。因此,当您将 NULL 作为参数传递给可变参数函数时,您必须小心,因为它可能会被误认为整数值 0,从而结束在非便携性方面。
http://c-faq.com/null/null2.html
顺便说一句,强烈建议每个 C 程序员阅读 comp.lang.c FAQ。例如,请参见此处:
http://c-faq.com/null/null1.html
包含诸如“如上所述,每种指针类型都有一个空指针,并且不同类型的空指针的内部值可能不同”之类的几乎被遗忘的智慧瑰宝。这意味着 calloc 或 memset 不是指针的可移植初始化。
In contrast to what some people state here, 0 is a perfectly valid definition for NULL in C. Thus you have to be careful when you give NULL as an argument to a variadic function, because it may be mistaken as the integer value 0, ending in non-portability.
http://c-faq.com/null/null2.html
BTW, the comp.lang.c FAQ is a highly recommended read for every C programmer. See for example here:
http://c-faq.com/null/null1.html
containing such gems of nearly-forgotten wisdom like "As mentioned above, there is a null pointer for each pointer type, and the internal values of null pointers for different types may be different." Which means that calloc or memset are NOT a portable initialization for pointers.
是 C 中的完美定义
,例如
它会导致错误,因为执行增量语句时 ch 没有指向任何内容
编译器通过查看 LOOK-UP 表中的指针值为 0 得知,
如果您尝试更新该指针,那么您实际上正在更改
从 0 物理地址开始的 CODE 区域。
因此,页表的第一个条目在代码区域之前开始
保持为空
从你应该的地方获取 NULL 到底有什么问题?即,
或者
正如 @Johannes Rudolph 的回答中提到的,面对类似的事情,你所做的任何欺骗都不太可能是未来的证明nullptr 等。
编辑:虽然 stdlib (和许多其他)被强制包含 NULL,但 stddef 是最规范的头文件 [并且已经存在了几十年]。
PS 一般来说,除非你有充分的理由,否则参与这种骗局是一个坏主意。你没有扩展让你觉得有必要这样做的想法。如果您可以添加一些细节,可能会得到更好的答案。回答这个问题的其他人也应该在他们的答案中指出这一点,但我想 FGITW 是最好的:D
编辑 2:正如@Yossarian 所指出的:这样做的唯一理由是如果没有在 中定义 NULL系统中其他地方的适当的与语言无关的形式。没有标头的裸编译器和/或如果您从头开始编写自己的自定义标准库就是这种情况的示例。 (在这种简单的情况下,我会选择@lilburne的答案(请确保尽可能使用0))
is the perfect definition in C
e.g.
it causes error since ch pointing to nothing while executing increment statement
is known by compiler by seeing the value of pointer in LOOK-UP table to be 0
if u try to update this pointer then u are actually changing the contents of
CODE region which start at 0 physical address.
FOR that reason the first entry of page table prior to code region starts
is kept empty
What exactly is the problem with getting your NULL from where you're supposed to?, i.e.,
or
as alluded to in @Johannes Rudolph's answer, any trickery you do is not likely be very future proof in the face of things like nullptr etc.
EDIT: while stdlib (and many others) are mandated to include a NULL, stddef is the most canonical header [and has been for decades].
PS In general, it's just a bad idea to get involved in this sort of trickery unless you have a really good reason. You didnt expand on the thinking that led you to feeling the need to do this. If you could add some detail on that, it's likely to lead to better answers. Other people answering the question should have pointed this out in their answers too, but I guess does FGITW as FGITW does best :D
EDIT 2: As pointed out by @Yossarian: The single justification for doing this is if there isnt a NULL defined in an appropriately language-agnostic form elsewhere in your system. Naked compilers with no headers and/or if you're writing your own custom standard library from scratch are examples of such a circumstance. (In such a bare-bones scenario, I'd go with @lilburne's answer (be sure to use 0 as much as possible))