tags:

views:

398

answers:

7

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?

+2  A: 
#define MYNULL 0

will work in C++

ArsenMkrt
This will work only for C++. C needs NULL to be #defined as (void *)0.
Paul R
Thanks!! It worked!
cppdev
So what is the best way it would work both in c and c++
cppdev
@Paul: defining `NULL` as `0` works fine in C, just you lose a slight bit of type safety. However, using `0` properly for `NULL` in C won't create any errors. If you are going to rebut with the varargs sentinel value, it is recommend to case to `char*` even when using `NULL`
Evan Teran
@Evan - you're right - I checked - thanks for correcting me !
Paul R
+26  A: 
#define MYNULL NULL

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:

#define NULL 0 //C++
#define NULL ((void*)0) //C

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:

Should I use NULL or 0?

In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days. If you have to name the null pointer, call it nullptr; that's what it's going to be called in C++0x. Then, "nullptr" will be a keyword.

Johannes Rudolph
+12  A: 
#ifdef __cplusplus
#define MYNULL 0
#else
#define MYNULL ((void*)0)
#endif

will work in both of them.

Yossarian
-1 This is a Bad Idea as covered in the other answers
Ruben Bartelink
Binary Worrier
@Binary Worrier: If you're building a ground-up replacement of an entire Standard Library for the new compiler you've just carefully crafted in order to do a landgrab for market share in the quickly expanding market of C/C++ compilers, this is an excellent idea. If you're not in that position, I fail to see how this is going to improve on what's built-in *and* not have any bad side-effects such as not playing well with `nullptr` as noted in @Johannes's answer or any other future things it might interact with.
Ruben Bartelink
There's an onus on people like Yossarian who understand this, to push back on bad ideas as in addition to the obvious purpose of this site, which is for the FGITWs to solve the programming problems of the planet in record time all the time.
Ruben Bartelink
Didnt call it out explicitly but any `<stdlib.h>` that's supplied with a C/C++ compiler (and definitely a `<cstdlib>`) explicitly worries about all this crap so the coder (and more importantly the maintainer and the porter doesnt have to)
Ruben Bartelink
The question was 'how to define NULL using #define in C++ and C', as I understood it, it wasn't 'what to do with NULL if I wait till someone implements c++0x well', or 'are there any caveats using NULL'. Why don't you just assume that cppdev KNOWS exactly is he doing, and just wants answer to this question? This is what I hate about stackoverflow - Usually I've got reasons for using my solutions, and don't want tips how to do it some other way. (well, the question doesn't have premises to assume this). Use your magic orbs and other future-seeing accessories for something more interesting.
Yossarian
@Yossarian: Part of a good question (deserving of many upvotes) is to FizzBin and/or otherwise establish what you have and havent tried to do on your road to deciding to bother the LazyWeb with your Important Question). And dont worry about being the only person on the planet that gets irked by SO and it's many + and (not so many) - points (in every sense of the term) :P But while we're splitting hairs, you really do think that, measured against all the other answers on the site, this one is uniquely worthy of 96 rep? (And no, my answer isnt worth 60 - its a dup of a comment). Go Johannnes!
Ruben Bartelink
I refer you to the comments on the question, the downvotes on yours, the upvotes on the comments on the question for independent verification lest you get too tied up in me being a Bad Guy. And @Binary Worrier: I'm blaming you for keeping this answer looking credible!
Ruben Bartelink
I don't mind the - points, I just don't like your argumentation.
Yossarian
Give me a -1 with a comment and someone willing to stand over their opinion and/or justify it with an explanation of why they feel its correct over a -1 any day. For subtle things like this question, letting mob rule sort things out based on potentially flawed understanding using downvotes to cancel out upvotes based on incomplete understandings is just not good enough. I have to say this nonsense happens a lot more on the tags on this question compared to others I look at. As I say, we all hate SO :(
Ruben Bartelink
I answered the question, the askee obviously wanted this answer. Your answer is bunch of what-ifs, speculating about c++0x, and assuming that there is correct standard library for platform askee is developing for.
Yossarian
@Ruben Bartelink: As I've said, I agree. Justified blame taken to heart. Also, I might be available for that VERY deserved pint somewhere around the end of March. Hope all's well pal :)
Binary Worrier
@Binary Worrier: In my blinded rage, I missed the subtlety in your original comment and actually construed it as saying 'it's OK in some circumstances' - see there were no smileys, exclamation marks or anything :D I believe it's certainly being used by the other arguee as a crutch for the purposes of scaling further up a high horse. If you have to wait until end March for a pint it will indeed be very well deserved. Suggest me a day other than Friday and I'll pencil it into the diary...
Ruben Bartelink
Congrats on solving this intriguing puzzler for our gallant questioner who can now continue on the road to writing a language independent library that's going to be really easy to port and maintain over time thanks to your unique insight. Seriously though, the net number of votes or points, whether a questioner accepts an answer doesnt really count for much. I'd love to find out what exotic platform and issue we're actually dealing with here :D
Ruben Bartelink
I'm not sure, if you ever left the x86/x64 platform, but there are lot of embedded systems without ANY standard library (but with working C/C++ compilers), your ignorance isn't any valuable argument.
Yossarian
@Ruben Bartelink: Zing! Point for Yossarian! (sorry, couldn't help myself)
Binary Worrier
Lets not get into a platforms contest or calling eachother ignorant. Remember I've assumed all along (correctly I believe) that you know this is a Bad Thing To Do. I wouldnt be engaging the services of anyone asking the question in the form it was asked in working with a hypothetical bare bones compiler without a single header file anywhere #defining NULL. PS While you're irked, can you go downvote Johannes too as his answer obviously isnt as fantastic as this one! @Binary Worrier: This is like a late nineties flamefest, complete with people egging them on!
Ruben Bartelink
Sorry for the term ignorance, english isn't my primary language, I didn't mean to be rude, just found out it in dictionary [meant lack of knowledge]. The 'bare-boned compiler' isn't hypothetical, it is widely used, again, if you're developing just for big systems, you cannot have any clue of other uses of C. I can even realize that someone needs this in 'big system' project nowadays. (so no, I don't think that this is in general BTTD).BTW: I'm not sure if you are the one to tell me who to up/downvote ;)
Yossarian
I am no authority on how to vote - just pointing out that putting random -1s on things without commenting isnt very cool unless you're going to have some consistency about it. As I said, not getting into platforms contest. And speculating about widespread fantastic compilers without any headers (maybe they dont even have a precompiler, hah :P) that the questioner is using is best left until it is confirmed that we're actually in that territory. In the meantime, I'm calling this relatively Bad Advice (despite being technically correct) and 19 people are calling Johannes' answer Good Advice.
Ruben Bartelink
And while we're descending into pedantry, the questioner said **redefine** so we have evidence of this *not* being a unicorn scenario. I take it you're using the recent upvotes (and lack of ones for @Johannes' answer) as further justification for feeling so supremely justified :P
Ruben Bartelink
Seems like I have missed a good flamewar whilst beeing at school :-( I agree with @Ruben, there's nothing wrong with Yossarians answer per se. (As a side note it's not explicitly stated the OP needs C backwards compatibility besides the wrong tagging, so please don't belabor on providing "unnescessary" information). However, my answer shows the same solution plus it gives a general advice, so it's open to the community to decide which is the better answer. Downvoting to neglect upvotes is a common practice here on SO and there's no serious reason to discourage it.
Johannes Rudolph
@Ruben and Yossarian: Great point about the bare-boned scenarios though.
Johannes Rudolph
+5  A: 

What exactly is the problem with getting your NULL from where you're supposed to?, i.e.,

#include <stddef.h>

or

 #include <cstddef>

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))

Ruben Bartelink
+1 for suggesting to go with the standard.
legends2k
@legends2k: Seems obvious to me (and @Neil Butterworth in the comments on the question but nobody +1'd that before me), but I guess people like solving puzzles that dont need to be solved.
Ruben Bartelink
@Ruben: Programmers, you see ;)
legends2k
@legends2k: You mean 'Hackers' ! I guess people aren't on this site because they believe everything on the planet that need's saying has already been said :P
Ruben Bartelink
@Ruben: Well 'hackers', but not all of 'em, many of them are though :)
legends2k
@-1er: Care to explain your downvote? if you have a reason why this is a wrong-headed answer, the world could benefit from the sharing of the reasoning. (I can offer a bunch of speculation and what-if's as to the identity of the mysterious voter if you wish!)
Ruben Bartelink
Ok. You solution assume working standard library. For developing ATMEL chips, there is C compiler, but NO standard library, no stddef.h. If you want to use NULL there, use maybe proprietal header, or define it yourself.
Yossarian
Ah, broadly applicable advise chopped down by a single insightful counterexample, wonderful. Nonetheless, will add proviso to cover this case which, while nit-picking in nature is possible.
Ruben Bartelink
@Ruben: Are there compilers with no standard library bundled? I.e. it only compiles code written in it's language with no support for standard library? I.e. you've to write functions for all your needs. I can't image this, the reason is, without malloc() or free() how will the programmer get memory (stack doesn't suffice always, I suppose)? Without having interrupt/signal (signal.h) how will the user handle signals from the OS?
legends2k
@legends2k: There is no reason to disbelieve Yossarian's example. However the general advise holds - for something like NULL, have a look around you before reinventing it. There was a time when many Cs didnt have a NULL (esp when it was just defined as `0`). But there's always something that calls main() and gives you stuff like allocation like you suggest (though one cant assume dynamic memory capabilities are avail or necessary). Point is all this pedantry is very far from the questioner's origin now. Esp when even considering C and C++ together(and C++ is much less likely to have no stdlib)
Ruben Bartelink
This discussion descended into someone arguing black is white a long time ago though - don't go looking for nuggets of insightful information in this snowstorm! (If your just looking to have your opinion confirmed, I agree, if you're looking to supply ammo, I'm getting bored !)
Ruben Bartelink
Neat. Understood it clearly! Thanks for taking the time to explain. (well, I'm a new recruit, no ammo here ;)
legends2k
@legends2k: Well then at least something good has come of the whole thing in the end - thanks for the kind words; Good luck!
Ruben Bartelink
+1  A: 

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

char* ch = NULL

and

char* ch = 0;

is minimal. When it comes to expressions the forms

if (NULL == ch) {
}
if (0 == ch) {
}
if (nullptr == ch) {
}

are no more readable than

if (!ch) {
}
lilburne
@lilburne: Bringing nullptr into your example muddies things rather than clarifying them. nullptr has a purpose and isnt always 100% interchangeable with NULL. But I agree with the general point that for most usages one should consider preferring `0` and implicit cooercion to int to `NULL`. (But it's not getting a +1 from me while it's conflating these issues :D)
Ruben Bartelink
A: 

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.

Secure
+1  A: 
Walt Stoneburner
this is a common mis-interpretation of the standard. The null pointer constant **is** 0. However the null pointer value (not exposed at a language level, so never your concern) may be machine specific.C99 standard 6.3.2.3: "An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function." Which basically says "0 used in a pointer context is NULL."
Evan Teran
Also see: http://stackoverflow.com/questions/1642763/null-pointer-equivalence-to-int/1642776#1642776 and http://stackoverflow.com/questions/423823/whats-your-favorite-programmer-ignorance-pet-peeve/1331729#1331729 and http://c-faq.com/null/machnon0.html
Evan Teran
@Walt: no problem, I'll remove my -1 now :-).
Evan Teran