A question about NULL

Discussion in 'C++' started by Dmitry D, Aug 16, 2003.

  1. Dmitry D

    Dmitry D Guest

    Hi,
    I'm new to C++ (started learning in the beginning of this summer), and I
    have the following question (sorry if it sounds stupid):
    In many code samples and source files, I see NULL expression being used (for
    example, int* someInt=NULL; ). I used similar initialization myself, and it
    works fine even if I don't define NULL. But what is "NULL" exactly? Is it a
    constant defined by compiler? Is there any difference between the following
    two ways to initialize a pointer?
    // example 1
    int * myInt = NULL;

    // example 2
    int * myInt = 0;

    If there is no difference, why would I use NULL instead of 0?
    Thanks in advance.

    Dmitry
    P.S. This is my first post in the newsgroup :)
    Dmitry D, Aug 16, 2003
    #1
    1. Advertising

  2. Dmitry D wrote:
    > Hi,
    > I'm new to C++ (started learning in the beginning of this summer), and I
    > have the following question (sorry if it sounds stupid):
    > In many code samples and source files, I see NULL expression being used (for
    > example, int* someInt=NULL; ). I used similar initialization myself, and it
    > works fine even if I don't define NULL. But what is "NULL" exactly? Is it a
    > constant defined by compiler? Is there any difference between the following
    > two ways to initialize a pointer?
    > // example 1
    > int * myInt = NULL;
    >
    > // example 2
    > int * myInt = 0;
    >
    > If there is no difference, why would I use NULL instead of 0?
    > Thanks in advance.
    >
    > Dmitry
    > P.S. This is my first post in the newsgroup :)


    NULL is usually a macro

    #define NULL 0

    and sometimes (but only for C as C++

    #define NULL ((void *) 0)


    '0' is a special case in the sense that

    int * ptr = 0; // happy compiler

    Is perfectly legal ... but

    int * ptr = 1; // Illegal - cranky compiler

    error: invalid conversion from `int' to `int*'


    Why NULL? Some would argue readability. Some would argue that NULL is
    not neccassarily '0', for example I *could* (but I would never) define
    NULL and ((void *) 1).

    NULL is usually defined in one of the standard header files.
    Gianni Mariani, Aug 16, 2003
    #2
    1. Advertising

  3. Dmitry D

    Tim Guest

    "Dmitry D" <> wrote in message
    news:xvk%a.63871$...
    > Hi,
    > I'm new to C++ (started learning in the beginning of this summer), and I
    > have the following question (sorry if it sounds stupid):
    > In many code samples and source files, I see NULL expression being used

    (for
    > example, int* someInt=NULL; ). I used similar initialization myself, and

    it
    > works fine even if I don't define NULL. But what is "NULL" exactly? Is it

    a
    > constant defined by compiler? Is there any difference between the

    following
    > two ways to initialize a pointer?
    > // example 1
    > int * myInt = NULL;
    >
    > // example 2
    > int * myInt = 0;


    In 'C', NULL is defined like this:

    #define NULL (void*)0


    In C++, NULL is defined like this:

    #define NULL 0


    If you try and initialise a pointer to a type with a pointer to void, you'll
    get errors with a C++ compiler:

    int* p = (void*)0; // OK in 'C*, error in C++
    int* p = 0; // OK in C++, error in 'C'


    C++ specifically forbids the 'C' style definition of NULL. Why? Perhaps
    assigning a 'pointer to a type' to the 'C' style NULL could be considered
    similar to assigning a 'pointer to a derived type' to a 'pointer to base
    type', which would be wrong. Then again, is assigning a 'pointer to a type'
    to the value zero is any more correct; besides which 'void' is not the base
    type of all types? You could say that it's a bit of shambles (I do). Then
    again, C++ isn't a real OO language; it's a baggage of OO extensions to 'C'
    which is, essentially, just portable assembler. To do the job properly, you
    would need a language that had a common base type for all types and Null
    instances of every derived type.
    Tim, Aug 16, 2003
    #3
  4. Dmitry D wrote in news:xvk%a.63871$:

    > Hi,
    > I'm new to C++ (started learning in the beginning of this summer), and
    > I have the following question (sorry if it sounds stupid):
    > In many code samples and source files, I see NULL expression being
    > used (for example, int* someInt=NULL; ). I used similar initialization
    > myself, and it works fine even if I don't define NULL. But what is
    > "NULL" exactly? Is it a constant defined by compiler? Is there any
    > difference between the following two ways to initialize a pointer?
    > // example 1
    > int * myInt = NULL;
    >
    > // example 2
    > int * myInt = 0;
    >
    > If there is no difference, why would I use NULL instead of 0?
    > Thanks in advance.
    >


    NULL is a #define's macro to use it you have to include one of
    the system header's that defines it, but don't use it.

    In C++ NULL is usually defined to be 0 or 0L, so there is no
    difference in the 2 examples you gave.

    In C NULL is usually defined to be ((void *)0), this is more
    "typesafe" in C.

    So the macro NULL is useful if you have some code that is going to
    bee seen by a C compiler and a C++ compiler, otherwise use 0 for C++.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Aug 16, 2003
    #4
  5. Dmitry D

    Tim Guest

    "Rolf Magnus" <> wrote in message
    news:bhkv82$blb$06$-online.com...
    > Rob Williscroft wrote:
    >
    > >> Hi,
    > >> I'm new to C++ (started learning in the beginning of this summer),
    > >> and I have the following question (sorry if it sounds stupid):
    > >> In many code samples and source files, I see NULL expression being
    > >> used (for example, int* someInt=NULL; ). I used similar
    > >> initialization myself, and it works fine even if I don't define NULL.
    > >> But what is "NULL" exactly? Is it a constant defined by compiler? Is
    > >> there any difference between the following two ways to initialize a
    > >> pointer? // example 1
    > >> int * myInt = NULL;
    > >>
    > >> // example 2
    > >> int * myInt = 0;
    > >>
    > >> If there is no difference, why would I use NULL instead of 0?
    > >> Thanks in advance.
    > >>

    > >
    > > NULL is a #define's macro to use it you have to include one of
    > > the system header's that defines it, but don't use it.
    > >
    > > In C++ NULL is usually defined to be 0 or 0L, so there is no
    > > difference in the 2 examples you gave.
    > >
    > > In C NULL is usually defined to be ((void *)0), this is more
    > > "typesafe" in C.

    >
    > Actually, it's not. It just fools the user into thinking that it's more
    > typesafe.


    Is that true? Surely it 'really' is safer to initialise a pointer to type
    with a ((void*)0); for instance, what about x86 segmented architecture;
    there 0 and (void*(0)) really are quite different animals (only the offset
    part of the pointer is zero).

    > > So the macro NULL is useful if you have some code that is going to
    > > bee seen by a C compiler and a C++ compiler, otherwise use 0 for C++.

    >
    > There is no reason to use NULL in C either.
    >


    ....but it makes the intention clear, namely that you're at least
    initialising a pointer to type with a pointer, not an integer.
    Tim, Aug 16, 2003
    #5
  6. Tim wrote:

    >
    > In 'C', NULL is defined like this:
    >
    > #define NULL (void*)0
    >
    >
    > In C++, NULL is defined like this:
    >
    > #define NULL 0
    >
    >


    NULL *may* be defined that way in C. It may also look like your second
    example. Both are acceptable in C, but only the second is acceptable in
    C++. However, it's not the *only* thing that's acceptable in C++. These
    are also legal definitions of NULL in C++:

    #define NULL 0L
    #define NULL (1 - 1)
    #define NULL !1
    #define NULL !!0
    #define NULL !!!!!!!!!!!!!!!!!!!!!!!!!!!1

    In C, I use NULL to make it more obvious that I'm dealing with pointers.
    In C++ that can be a dangerous way of thinking, because NULL is *not*,
    in fact, a pointer. So if you have an overloaded function:

    void f(long i);
    void f(void *p);

    And you attempt to call f(void *) this way:

    f(NULL);

    You will call the wrong function. NULL can lead you to believe you are
    using a pointer when, if fact, you are not.

    Technically, NULL can also be changed in a program:

    #undef NULL
    #define NULL 27

    Which could cause serious problems. This is another reason to avoid it
    and use 0 instead, but I think this one is a bit of a stretch. I can't
    imagine why someone would do something like that.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Aug 16, 2003
    #6
  7. Dmitry D

    Jack Klein Guest

    On 16 Aug 2003 08:17:09 GMT, Gianni Mariani <>
    wrote in comp.lang.c++:

    > Dmitry D wrote:
    > > Hi,
    > > I'm new to C++ (started learning in the beginning of this summer), and I
    > > have the following question (sorry if it sounds stupid):
    > > In many code samples and source files, I see NULL expression being used (for
    > > example, int* someInt=NULL; ). I used similar initialization myself, and it
    > > works fine even if I don't define NULL. But what is "NULL" exactly? Is it a
    > > constant defined by compiler? Is there any difference between the following
    > > two ways to initialize a pointer?
    > > // example 1
    > > int * myInt = NULL;
    > >
    > > // example 2
    > > int * myInt = 0;
    > >
    > > If there is no difference, why would I use NULL instead of 0?
    > > Thanks in advance.
    > >
    > > Dmitry
    > > P.S. This is my first post in the newsgroup :)

    >
    > NULL is usually a macro


    Actually the C and C++ standards both require that NULL is a macro.

    > #define NULL 0
    >
    > and sometimes (but only for C as C++
    >
    > #define NULL ((void *) 0)
    >
    >
    > '0' is a special case in the sense that
    >
    > int * ptr = 0; // happy compiler
    >
    > Is perfectly legal ... but
    >
    > int * ptr = 1; // Illegal - cranky compiler
    >
    > error: invalid conversion from `int' to `int*'
    >
    >
    > Why NULL? Some would argue readability. Some would argue that NULL is
    > not neccassarily '0', for example I *could* (but I would never) define
    > NULL and ((void *) 1).


    NULL, at least in C++, is necessarily 0, although it may not be the
    literal character constant '0'. The C++ language standard requires
    that the macro NULL expand to an integer constant expression that
    evaluates to 0.

    So it could be:

    #define NULL (42-4*7)

    ....but it can't be defined as ((void *)1). In fact it can't be
    defined as a pointer at all in C++. It can in C, but only (again) as
    an integer constant expression that evaluates to 0 being cast to a
    pointer to void.

    > NULL is usually defined in one of the standard header files.


    NULL is required to be defined in several of the standard header
    files.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
    Jack Klein, Aug 16, 2003
    #7
  8. Dmitry D

    Jack Klein Guest

    On Sat, 16 Aug 2003 20:46:52 +0200, "Tim" <> wrote
    in comp.lang.c++:

    >
    > "Rolf Magnus" <> wrote in message
    > news:bhkv82$blb$06$-online.com...
    > > Rob Williscroft wrote:
    > >
    > > >> Hi,
    > > >> I'm new to C++ (started learning in the beginning of this summer),
    > > >> and I have the following question (sorry if it sounds stupid):
    > > >> In many code samples and source files, I see NULL expression being
    > > >> used (for example, int* someInt=NULL; ). I used similar
    > > >> initialization myself, and it works fine even if I don't define NULL.
    > > >> But what is "NULL" exactly? Is it a constant defined by compiler? Is
    > > >> there any difference between the following two ways to initialize a
    > > >> pointer? // example 1
    > > >> int * myInt = NULL;
    > > >>
    > > >> // example 2
    > > >> int * myInt = 0;
    > > >>
    > > >> If there is no difference, why would I use NULL instead of 0?
    > > >> Thanks in advance.
    > > >>
    > > >
    > > > NULL is a #define's macro to use it you have to include one of
    > > > the system header's that defines it, but don't use it.
    > > >
    > > > In C++ NULL is usually defined to be 0 or 0L, so there is no
    > > > difference in the 2 examples you gave.
    > > >
    > > > In C NULL is usually defined to be ((void *)0), this is more
    > > > "typesafe" in C.

    > >
    > > Actually, it's not. It just fools the user into thinking that it's more
    > > typesafe.

    >
    > Is that true? Surely it 'really' is safer to initialise a pointer to type
    > with a ((void*)0); for instance, what about x86 segmented architecture;
    > there 0 and (void*(0)) really are quite different animals (only the offset
    > part of the pointer is zero).


    You have some misunderstandings here. First, C++ disallowed the C
    definition of NULL as (void *)0 because it runs afoul of the typing
    system. The following is legal C but illegal C++:

    char *cp = (void *)0;

    C allows conversion to and from void pointer to any object type
    without a cast, C++ only allows the conversion from pointer to object
    to void pointer, not the other way.

    Second, perhaps you misunderstand something else. An integer constant
    expression that evaluates to 0 is "magic" in C and C++ when used in a
    pointer context. It makes no difference what the size of a pointer
    is, or whether the architecture is segmented or has other unusual
    quirks.

    The expression:

    type *type_pointer = 0;

    ....sets the pointer to a null pointer. That does not mean that a null
    pointer has all bits 0 in its physical representation.

    The compiler must recognize the use of such an expression at compile
    time, and convert it to whatever the implementation uses internally as
    an actual null pointer value.

    Note that this only applies to compile time constant expressions. The
    following:

    int x = 0;
    char *cp;
    cp = x;

    ....is not guaranteed to make cp a null pointer.

    Compilers have been required to perform this recognition and special
    handling for constant 0 in a pointer context for at least 30 years
    now, long before K&R1, long before the first ANSI C standard, and long
    before Bjarne started extending C into C++.

    >
    > > > So the macro NULL is useful if you have some code that is going to
    > > > bee seen by a C compiler and a C++ compiler, otherwise use 0 for C++.

    > >
    > > There is no reason to use NULL in C either.
    > >

    >
    > ...but it makes the intention clear, namely that you're at least
    > initialising a pointer to type with a pointer, not an integer.


    This is the most important point. The three most common expressions
    for 0 in C++ are 0, '\0', and NULL.

    You could write:

    char *cp = '\0'; // '\0' is a perfectly valid null pointer constant!

    You could also write:

    char ca [100];
    ca [99] = NULL;

    ....but you wouldn't last long working on any project I was running!

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
    Jack Klein, Aug 16, 2003
    #8
  9. Dmitry D

    Artie Gold Guest

    Jack Klein wrote:
    [snip]
    >
    >
    > NULL, at least in C++, is necessarily 0, although it may not be the
    > literal character constant '0'. The C++ language standard requires
    > that the macro NULL expand to an integer constant expression that
    > evaluates to 0.
    >
    > So it could be:
    >
    > #define NULL (42-4*7)


    OK Jack. It's Saturday. Step away from the keyboard. Easy now...

    ;-)

    --ag
    --
    Artie Gold -- Austin, Texas
    Artie Gold, Aug 16, 2003
    #9
  10. Rob Williscroft <> wrote in message news:<Xns93D95EC6D19E9ukcoREMOVEfreenetrtw@195.129.110.200>...
    > NULL is a #define's macro to use it you have to include one of
    > the system header's that defines it, but don't use it.
    >
    > In C++ NULL is usually defined to be 0 or 0L, so there is no
    > difference in the 2 examples you gave.
    >
    > In C NULL is usually defined to be ((void *)0), this is more
    > "typesafe" in C.
    >
    > So the macro NULL is useful if you have some code that is going to
    > bee seen by a C compiler and a C++ compiler, otherwise use 0 for C++.


    Your conclusion doesn't follow. How is it "useful" to have the
    definition of NULL change? All it can do is introduce bugs.

    For example:

    printf("%p", NULL);

    is legal if NULL=(void*)0, but a bug if NULL=0.

    Sam
    Samuel Barber, Aug 17, 2003
    #10
  11. Jack Klein <> wrote in message news:<>...
    > Compilers have been required to perform this recognition and special
    > handling for constant 0 in a pointer context for at least 30 years
    > now, long before K&R1, long before the first ANSI C standard, and long
    > before Bjarne started extending C into C++.


    I don't think that's historically accurate. In the very early C days,
    it was permitted to mix integers and pointers (without casts), so 0
    wasn't treated differently than any other integer.

    From http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

    "The language changes during this period, especially around 1977, were
    largely focused on considerations of portability and type safety, in
    an effort to cope with the problems we foresaw and observed in moving
    a considerable body of code to the new Interdata platform. C at that
    time still manifested strong signs of its typeless origins. Pointers,
    for example, were barely distinguished from integral memory indices in
    early language manuals or extant code; the similarity of the
    arithmetic properties of character pointers and unsigned integers made
    it hard to resist the temptation to identify them. The unsigned types
    were added to make unsigned arithmetic available without confusing it
    with pointer manipulation. Similarly, the early language condoned
    assignments between integers and pointers, but this practice began to
    be discouraged; a notation for type conversions (called `casts' from
    the example of Algol 68) was invented to specify type conversions more
    explicitly. ..."

    "Compilers in 1977, and even well after, did not complain about usages
    such as assigning between integers and pointers or using objects of
    the wrong type to refer to structure members. Although the language
    definition presented in the first edition of K&R was reasonably
    (though not completely) coherent in its treatment of type rules, that
    book admitted that existing compilers didn't enforce them."

    Sam
    Samuel Barber, Aug 17, 2003
    #11
  12. Dmitry D

    Tim Guest

    "Jack Klein" <> wrote in message
    news:...
    > On Sat, 16 Aug 2003 20:46:52 +0200, "Tim" <> wrote
    > in comp.lang.c++:
    >
    > >
    > > "Rolf Magnus" <> wrote in message
    > > news:bhkv82$blb$06$-online.com...
    > > > Rob Williscroft wrote:
    > > >
    > > > >> Hi,
    > > > >> I'm new to C++ (started learning in the beginning of this summer),
    > > > >> and I have the following question (sorry if it sounds stupid):
    > > > >> In many code samples and source files, I see NULL expression being
    > > > >> used (for example, int* someInt=NULL; ). I used similar
    > > > >> initialization myself, and it works fine even if I don't define

    NULL.
    > > > >> But what is "NULL" exactly? Is it a constant defined by compiler?

    Is
    > > > >> there any difference between the following two ways to initialize a
    > > > >> pointer? // example 1
    > > > >> int * myInt = NULL;
    > > > >>
    > > > >> // example 2
    > > > >> int * myInt = 0;
    > > > >>
    > > > >> If there is no difference, why would I use NULL instead of 0?
    > > > >> Thanks in advance.
    > > > >>
    > > > >
    > > > > NULL is a #define's macro to use it you have to include one of
    > > > > the system header's that defines it, but don't use it.
    > > > >
    > > > > In C++ NULL is usually defined to be 0 or 0L, so there is no
    > > > > difference in the 2 examples you gave.
    > > > >
    > > > > In C NULL is usually defined to be ((void *)0), this is more
    > > > > "typesafe" in C.
    > > >
    > > > Actually, it's not. It just fools the user into thinking that it's

    more
    > > > typesafe.

    > >
    > > Is that true? Surely it 'really' is safer to initialise a pointer to

    type
    > > with a ((void*)0); for instance, what about x86 segmented architecture;
    > > there 0 and (void*(0)) really are quite different animals (only the

    offset
    > > part of the pointer is zero).

    >
    > You have some misunderstandings here. First, C++ disallowed the C
    > definition of NULL as (void *)0 because it runs afoul of the typing
    > system. The following is legal C but illegal C++:
    >
    > char *cp = (void *)0;
    >
    > C allows conversion to and from void pointer to any object type
    > without a cast, C++ only allows the conversion from pointer to object
    > to void pointer, not the other way.
    >


    Why would you think I have a misunderstanding here; all you've done is
    repeat what I said in an earlier reply in this thread?

    > Second, perhaps you misunderstand something else. An integer constant


    ....that would be in addition to the first thing that I actually understood,
    would it?

    > expression that evaluates to 0 is "magic" in C and C++ when used in a
    > pointer context. It makes no difference what the size of a pointer
    > is, or whether the architecture is segmented or has other unusual
    > quirks.
    >
    > The expression:
    >
    > type *type_pointer = 0;
    >
    > ...sets the pointer to a null pointer. That does not mean that a null
    > pointer has all bits 0 in its physical representation.
    >
    > The compiler must recognize the use of such an expression at compile
    > time, and convert it to whatever the implementation uses internally as
    > an actual null pointer value.
    >
    > Note that this only applies to compile time constant expressions. The
    > following:
    >
    > int x = 0;
    > char *cp;
    > cp = x;
    >
    > ...is not guaranteed to make cp a null pointer.
    >
    > Compilers have been required to perform this recognition and special
    > handling for constant 0 in a pointer context for at least 30 years
    > now, long before K&R1, long before the first ANSI C standard, and long
    > before Bjarne started extending C into C++.


    I could be wrong (it was a long time a go) but going back to the days of
    Microsoft C 5 (about 15 years a go?), I think you'll find that you would
    have had problems if you initialised pointers to 0 (instead of ((void
    far*)0) or ((void near*)0) or ((void huge*)0).

    > >
    > > > > So the macro NULL is useful if you have some code that is going to
    > > > > bee seen by a C compiler and a C++ compiler, otherwise use 0 for

    C++.
    > > >
    > > > There is no reason to use NULL in C either.
    > > >

    > >
    > > ...but it makes the intention clear, namely that you're at least
    > > initialising a pointer to type with a pointer, not an integer.

    >
    > This is the most important point. The three most common expressions
    > for 0 in C++ are 0, '\0', and NULL.
    >
    > You could write:
    >
    > char *cp = '\0'; // '\0' is a perfectly valid null pointer constant!
    >
    > You could also write:
    >
    > char ca [100];
    > ca [99] = NULL;
    >
    > ...but you wouldn't last long working on any project I was running!
    >
    > --
    > Jack Klein
    > Home: http://JK-Technology.Com
    > FAQs for
    > comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    > comp.lang.c++ http://www.parashift.com/c -faq-lite/
    > alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
    Tim, Aug 17, 2003
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kivak Wolf
    Replies:
    2
    Views:
    10,059
    Kivak Wolf
    Jun 28, 2005
  2. vizlab
    Replies:
    3
    Views:
    4,173
    Michael Bar-Sinai
    Oct 17, 2007
  3. Replies:
    16
    Views:
    7,287
    Mike Schilling
    Oct 12, 2005
  4. Replies:
    5
    Views:
    26,493
    Mike Schilling
    Mar 29, 2006
  5. Bo Peng
    Replies:
    13
    Views:
    13,267
    Siemel Naran
    Jul 18, 2004
Loading...

Share This Page