Pointer arithmetic involving NULL pointers

Discussion in 'C Programming' started by Christopher Benson-Manica, Sep 10, 2004.

  1. Is adding 0 to a pointer to non-void that is equal to NULL legal?

    int *p=NULL;
    p+=0;

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Sep 10, 2004
    #1
    1. Advertising

  2. Christopher Benson-Manica

    Eric Sosman Guest

    Christopher Benson-Manica wrote:
    > Is adding 0 to a pointer to non-void that is equal to NULL legal?
    >
    > int *p=NULL;
    > p+=0;


    Never considered it before, but I think it's undefined.

    6.5.6 Additive operators
    /8/ [...] If both the pointer operand and the result
    point to elements of the same array object, or one past
    the last element of the array object, the evaluation
    shall not produce an overflow; otherwise, the behavior
    is undefined. [...]

    Since `p' above does not point to any element of any array
    object, the "otherwise" holds.

    If you don't mind my asking, what are you trying to do?
    I've added zero to a pointer value plenty of times, as in

    char *p = string_with_possible_leading_spaces;
    p += strspn(p, " \t\f\n\r";

    .... but I can't recall being tempted to do any such thing
    with a NULL value. What's up?

    --
     
    Eric Sosman, Sep 10, 2004
    #2
    1. Advertising

  3. In article <chsudn$ssj$>,
    Christopher Benson-Manica <> wrote:
    >Is adding 0 to a pointer to non-void that is equal to NULL legal?
    >
    >int *p=NULL;
    >p+=0;


    No; pointer addition is only defined for pointers to or one past a valid
    object, so adding anything (even 0) to a null pointer is undefined.
    (N869 6.5.6#8, see also #7.)

    (But the sigmonster made a good choice today.)


    dave

    --
    Dave Vandervies
    I would lodge a serious QOI complaint with the compiler vendor if either of
    these reformatted my nose or caused Scott Nudds to fly out of my hard drive.
    --Jack Klein in comp.lang.c
     
    Dave Vandervies, Sep 10, 2004
    #3
  4. Christopher Benson-Manica <> writes:
    > Is adding 0 to a pointer to non-void that is equal to NULL legal?
    >
    > int *p=NULL;
    > p+=0;


    No, it invokes undefined behavior. C99 6.5.6p4 says:

    When an expression that has integer type is added to or subtracted
    from a pointer, the result has the type of the pointer operand.
    [...]
    If both the pointer operand and the result point to elements of
    the same array object, or one past the last element of the array
    object, the evaluation shall not produce an overflow; otherwise,
    the behavior is undefined.

    There's no stated exception for adding 0. The C90 standard has
    similar or identical wording.

    On most implementations, the operation won't cause a trap, and the
    result will compare equal to NULL -- which is, of course, a valid
    consequence of undefined behavior.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 10, 2004
    #4
  5. Christopher Benson-Manica wrote:
    > Is adding 0 to a pointer to non-void that is equal to NULL legal?
    >
    > int *p=NULL;
    > p+=0;
    >
    > --
    > Christopher Benson-Manica | I *should* know what I'm talking about - if
    > I
    > ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    >


    A pointer is nothiner else than a piece of memory with the right size to
    store a memory address. Normally this is 4 bytes, but this may be different
    on other different computers. You can do anything with this memory you can
    do with other memory. This includes adding things to it - in this case 0.
    The problem which make things illegal isn't that the pointer *is* NULL (=
    0), but that the data the pointer points to is accessed. The pointer points
    to the memory address 0, which can't be accessed.

    So p += 0; would be valid, but it would keep the pointer to 0 (NULL). So
    accessing this memory still is invalid. But with the pointer itself, you
    can do anything. As long as the data the pointer points to isn't accessed.

    But why not just use an "int" for example. Should you ever need the data it
    points to, you can simply use:
    (int*)theinteger




    Hope that helps,
    Spoofed Existence

    --
    This message has been sent using the astalavista.net newsreader
    webinterface.
    http://www.astalavista.net/
     
    Spoofed Existence (astalavista.net), Sep 10, 2004
    #5
  6. Eric Sosman <> spoke thus:

    > ... but I can't recall being tempted to do any such thing
    > with a NULL value. What's up?


    Well, the situation is something like the following:

    void foo( char *buf, int bufsize )
    {
    bar( buf, buf?bufsize:0 );
    /* Call other functions like bar, with the same parameters */
    }

    void bar( char *buf, int bufsize )
    {
    int bytes_remaining=bufsize;

    bytes_remaining-=snprintf( buf+(bufsize-bytes_remaining), bytes_remaining, "Hello, world!\n" );

    /* Call snprintf in the same way several more times */
    }

    snprintf() is C99, correct?

    Assuming I've made no other errors here, this strikes me as being
    fairly concise code. Of course, I could call bar as

    bar( buf?buf:"", buf?bufsize:0 );

    and eliminate the probable undefined behavior, but presumably nothing
    catastrophic will occur on the particular real implementation I'm
    using with the code as is.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Sep 10, 2004
    #6
  7. In article <chsudn$ssj$>,
    Christopher Benson-Manica <> wrote:

    > Is adding 0 to a pointer to non-void that is equal to NULL legal?
    >
    > int *p=NULL;
    > p+=0;


    It is undefined behavior.
     
    Christian Bau, Sep 10, 2004
    #7
  8. In article <cht1bu$set$-plus.net>,
    "Spoofed Existence (astalavista.net)"
    <> wrote:

    Warning to every reader: What follows is absolutely wrong.

    > A pointer is nothiner else than a piece of memory with the right size to
    > store a memory address. Normally this is 4 bytes, but this may be different
    > on other different computers. You can do anything with this memory you can
    > do with other memory. This includes adding things to it - in this case 0.
    > The problem which make things illegal isn't that the pointer *is* NULL (=
    > 0), but that the data the pointer points to is accessed. The pointer points
    > to the memory address 0, which can't be accessed.
    >
    > So p += 0; would be valid, but it would keep the pointer to 0 (NULL). So
    > accessing this memory still is invalid. But with the pointer itself, you
    > can do anything. As long as the data the pointer points to isn't accessed.


    Please stop giving incorrect advice.
     
    Christian Bau, Sep 10, 2004
    #8
  9. "Spoofed Existence (astalavista.net)"
    <> writes:
    > Christopher Benson-Manica wrote:
    >> Is adding 0 to a pointer to non-void that is equal to NULL legal?
    >>
    >> int *p=NULL;
    >> p+=0;

    >
    > A pointer is nothiner else than a piece of memory with the right size to
    > store a memory address. Normally this is 4 bytes, but this may be different
    > on other different computers.


    4 bytes is a common size for pointers, but there's nothing abnormal
    about other sizes.

    > You can do anything with this memory you can
    > do with other memory. This includes adding things to it - in this case 0.


    You can do anything you want to with the *memory* (e.g., if you treat
    it as an array of unsigned char), but the language limits what you can
    do with it as a pointer. In particular, performing arithmetic on a
    null pointer invokes undefined behavior, as has been explained
    elsewhere in this thread.

    > The problem which make things illegal isn't that the pointer *is* NULL (=
    > 0), but that the data the pointer points to is accessed. The pointer points
    > to the memory address 0, which can't be accessed.


    No, the problem is precisely that it's a null pointer. As far as the
    C language is concerned, a null pointer doesn't point to "memory
    address 0"; it doesn't point to *anything*. (A null pointer is not
    necessarily represented as all-bits-zero; see the FAQ.)

    > So p += 0; would be valid, but it would keep the pointer to 0 (NULL). So
    > accessing this memory still is invalid. But with the pointer itself, you
    > can do anything. As long as the data the pointer points to isn't accessed.


    That's incorrect. On many systems, p += 0; will result in p being
    equal to NULL; that's just one of the many possible consequences of
    undefined behavior.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 10, 2004
    #9
  10. Christopher Benson-Manica <> spoke thus:

    > bar( buf?buf:"", buf?bufsize:0 );


    Or, to post code that's actually legal,

    if( !buf ) {
    buf="";
    bufsize=0;
    }

    Maybe I should A) go home, and B) never use the trinary operator in
    function calls again. Sorry.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Sep 10, 2004
    #10
  11. Christopher Benson-Manica

    DD Guest

    "Keith Thompson" <> wrote in message
    news:...
    > "Spoofed Existence (astalavista.net)"
    > <> writes:
    > > Christopher Benson-Manica wrote:
    > >> Is adding 0 to a pointer to non-void that is equal to NULL legal?
    > >>
    > >> int *p=NULL;
    > >> p+=0;

    > >
    > > A pointer is nothiner else than a piece of memory with the right size to
    > > store a memory address. Normally this is 4 bytes, but this may be

    different
    > > on other different computers.

    >
    > 4 bytes is a common size for pointers, but there's nothing abnormal
    > about other sizes.
    >
    > > You can do anything with this memory you

    can
    > > do with other memory. This includes adding things to it - in this case

    0.
    >
    > You can do anything you want to with the *memory* (e.g., if you treat
    > it as an array of unsigned char), but the language limits what you can
    > do with it as a pointer. In particular, performing arithmetic on a
    > null pointer invokes undefined behavior, as has been explained
    > elsewhere in this thread.
    >
    > > The problem which make things illegal isn't that the pointer *is* NULL

    (=
    > > 0), but that the data the pointer points to is accessed. The pointer

    points
    > > to the memory address 0, which can't be accessed.

    >
    > No, the problem is precisely that it's a null pointer. As far as the
    > C language is concerned, a null pointer doesn't point to "memory
    > address 0"; it doesn't point to *anything*. (A null pointer is not
    > necessarily represented as all-bits-zero; see the FAQ.)

    Isn't it true that in most applications "NULL" is defined as 0 ? So
    essentially in most applications the null pointer would be pointing to
    address 0. Correct me if I am wrong.
    >
    > > So p += 0; would be valid, but it would keep the pointer to 0 (NULL). So
    > > accessing this memory still is invalid. But with the pointer itself, you
    > > can do anything. As long as the data the pointer points to isn't

    accessed.
    >
    > That's incorrect. On many systems, p += 0; will result in p being
    > equal to NULL; that's just one of the many possible consequences of
    > undefined behavior.
    >
    > --
    > Keith Thompson (The_Other_Keith)

    <http://www.ghoti.net/~kst>
    > San Diego Supercomputer Center <*>

    <http://users.sdsc.edu/~kst>
    > We must do something. This is something. Therefore, we must do this.
     
    DD, Sep 10, 2004
    #11
  12. >Isn't it true that in most applications "NULL" is defined as 0 ? So

    No! Applications have no business defining NULL at all, especially
    if any of the ANSI C headers that are supposed to define NULL are included
    (such as <stdlib.h>).

    >essentially in most applications the null pointer would be pointing to
    >address 0. Correct me if I am wrong.


    The presence of:
    #define NULL 0
    or
    #define NULL ((void *) 0)
    in an ANSI C header file does not prohibit the implementation from
    using a bit pattern of 0xdeadbeef for a null pointer. The use of
    0xdeadbeef is not required, even if pointers are 32 bits. The use
    of 0xdeadbeefdeadbeef is not required, even if pointers are 64 bits.

    >> > So p += 0; would be valid, but it would keep the pointer to 0 (NULL). So


    This is one possible outcome, but it is not guaranteed. A smegmentation
    violation due to loading an invalid value into a smegment register
    is another. Undefined is undefined.

    >> > accessing this memory still is invalid. But with the pointer itself, you
    >> > can do anything.


    Incorrect. With the pointer itself, the *IMPLEMENTATION* can do
    anything, since you invoked the wrath of undefined behavior,
    regardless of how painful, embarassing, or expensive it is for you.
    You don't get to choose.

    >As long as the data the pointer points to isn't
    >accessed.
    >>
    >> That's incorrect. On many systems, p += 0; will result in p being
    >> equal to NULL; that's just one of the many possible consequences of
    >> undefined behavior.


    Gordon L. Burditt
     
    Gordon Burditt, Sep 10, 2004
    #12
  13. Christopher Benson-Manica

    Eric Sosman Guest

    DD wrote:
    >
    > Isn't it true that in most applications "NULL" is defined as 0 ? So
    > essentially in most applications the null pointer would be pointing to
    > address 0. Correct me if I am wrong.


    You're wrong ;-) Please see Section 5 -- yes, all of it --
    in the comp.lang.c Frequently Asked Questions (FAQ) list

    http://www.eskimo.com/~scs/C-faq/top.html

    --
     
    Eric Sosman, Sep 10, 2004
    #13
  14. Christian Bau wrote:
    > In article <cht1bu$set$-plus.net>,
    > "Spoofed Existence (astalavista.net)"
    > <> wrote:
    >
    > Warning to every reader: What follows is absolutely wrong.
    >
    >> A pointer is nothiner else than a piece of memory with the right

    > size to
    >> store a memory address. Normally this is 4 bytes, but this may be

    > different
    >> on other different computers. You can do anything with this memory

    > you can
    >> do with other memory. This includes adding things to it - in this

    > case 0.
    >> The problem which make things illegal isn't that the pointer *is*

    > NULL (=
    >> 0), but that the data the pointer points to is accessed. The

    > pointer points
    >> to the memory address 0, which can't be accessed.
    >>
    >> So p += 0; would be valid, but it would keep the pointer to 0

    > (NULL). So
    >> accessing this memory still is invalid. But with the pointer

    > itself, you
    >> can do anything. As long as the data the pointer points to isn't

    > accessed.
    >
    > Please stop giving incorrect advice.
    >


    I'm sorry. The compiler I use, gcc 3.3.4, defines NULL as (void*)0. Also,
    gcc can use mathematic expressions on it, although some things will need
    some changes.
    So I assumed this was just a standard. Well, I never read about any
    standards, and I basically learned C by trying things, and by reading. But
    I never really learned about other compilers than gcc. Might be a good idea
    to do it sometime.

    --
    This message has been sent using the astalavista.net newsreader
    webinterface.
    http://www.astalavista.net/
     
    Spoofed Existence (astalavista.net), Sep 11, 2004
    #14
  15. "Spoofed Existence (astalavista.net)"
    <> writes:
    [...]
    > I'm sorry. The compiler I use, gcc 3.3.4, defines NULL as (void*)0. Also,
    > gcc can use mathematic expressions on it, although some things will need
    > some changes.


    The definition of NULL is determined by the system's headers, which
    may be, but aren't necessarily, from the same source as your compiler.

    The definition of NULL as (void*)0 does *not* necessarily mean that
    the representation of a null pointer is all-bits-zero.

    (GNU C allows arithmetic on void* pointers; standard C does not.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 11, 2004
    #15
  16. In article <chukgg$7qp$-plus.net>,
    "Spoofed Existence (astalavista.net)"
    <> wrote:

    > The compiler I use, gcc 3.3.4, defines NULL as (void*)0.


    Yes, and that is completely irrelevant. The C language defines that "0"
    and "(void*) 0" have to be specifically recognised by the compiler and
    then have to be replaced by a null pointer. Whatever a null pointer is.

    > Also,
    > gcc can use mathematic expressions on it, although some things will need
    > some changes.
    > So I assumed this was just a standard.


    The original question was: Is pointer arithmetic with null pointers
    undefined behavior? Undefined behavior means: Anything, just absolutely
    anything, can happen. And "anything can happen" includes that it seems
    to work if you use the current version of the gcc compiler.

    > Well, I never read about any
    > standards, and I basically learned C by trying things, and by reading. But
    > I never really learned about other compilers than gcc. Might be a good idea
    > to do it sometime.


    If you learn about the C Standard itself instead of other compilers,
    that would have the advantage that you learn what exactly is
    _guaranteed_ to work and what is _not guaranteed_ to work. If something
    is guaranteed to work then you don't have to learn about other
    compilers, it will work.

    If something is not guaranteed to work, like adding 0 to a null pointer,
    then you are asking for trouble if you use a different compiler, or if
    you use a different version of the compiler, or if you turn optimisation
    on or off, or if you slightly rearrange your code in a way that
    shouldn't make any difference. In all these cases, something that
    "worked" by coincidence can suddenly stop working.
     
    Christian Bau, Sep 11, 2004
    #16
  17. Christian Bau wrote:
    > If you learn about the C Standard itself instead of other compilers,
    > that would have the advantage that you learn what exactly is
    > _guaranteed_ to work and what is _not guaranteed_ to work. If something
    > is guaranteed to work then you don't have to learn about other
    > compilers, it will work.


    You make the opposite error - the assumption that other compilers are
    compliant. If a particular noncompliant compiler is influential enough,
    people writing portable code will strive to observe its quirks as well
    as the standard. A good example is Visual C++'s problem with the scope
    of variables declared in for loop initializers (although that's not a C
    example; I think most modern C compilers are pretty much compliant, right?)
    --
    Derrick Coetzee
    I grant this newsgroup posting into the public domain. I disclaim all
    express or implied warranty and all liability. I am not a professional.
     
    Derrick Coetzee, Sep 12, 2004
    #17
  18. Christopher Benson-Manica

    Chris Barts Guest

    On Sat, 11 Sep 2004 20:54:27 -0400, Derrick Coetzee wrote:

    > I think most modern C compilers are pretty much compliant, right?


    No important compiler is C99 compliant. (C99 is looking more and more like
    a dead issue as time goes by, and it's difficult to imagine that
    nonconformance with C99 will ever be a hindrance to a compiler's
    popularity.) The GNU C Compiler is in the happy position of having some of
    its historical extensions codified in C99, so it's partially there with
    the stated intent of full support, IIRC.

    C89 is very widely supported, and C90 can usually be assumed, as well. C89
    is what this newsgroup implicitly assumes when it says "standard", and
    C99-specific things are always introduced as such. However, I don't know
    of any compiler that correctly compiles only C89 (as opposed to C89 plus
    extensions) by default.
     
    Chris Barts, Sep 12, 2004
    #18
  19. In article <cht1bu$set$-plus.net>, "Spoofed Existence (astalavista.net)" <> writes:
    >
    > A pointer is nothiner else than a piece of memory with the right size to
    > store a memory address.


    While we're pointing out errors here, I'd like to note that a pointer
    can contain something other than a simple address; and there is at
    least one implementation (AS/400 ILE C) which I believe is conforming
    and which does so. (ILE C pointers contain some kind of reference to
    a "memory space" and an offset into that space, and possibly other
    information; some of this can be seen by displaying the value of a
    valid non-null pointer with the "%p" printf specifier.)

    So besides not assuming that null pointers have the value all-bits-
    zero, you shouldn't assume that non-null pointers have just a simple
    address.

    --
    Michael Wojcik

    Only the obscene machine has persisted
    jerky and jockeying and not knowing why
    I have never existed. Nor should. -- George Barker
     
    Michael Wojcik, Sep 12, 2004
    #19
  20. Christopher Benson-Manica

    Richard Bos Guest

    (Gordon Burditt) wrote:

    > A smegmentation violation


    A crashing Red Dwarf?

    Richard
     
    Richard Bos, Sep 13, 2004
    #20
    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. Kavya
    Replies:
    2
    Views:
    389
  2. aneuryzma
    Replies:
    3
    Views:
    745
    Jim Langston
    Jun 16, 2008
  3. Urs Thuermann

    Arithmetic will null pointer

    Urs Thuermann, Jun 16, 2010, in forum: C Programming
    Replies:
    19
    Views:
    928
    Tim Rentsch
    Jun 20, 2010
  4. Christopher
    Replies:
    4
    Views:
    455
    Ruben Safir
    Jul 9, 2011
  5. Replies:
    32
    Views:
    1,200
    Tim Rentsch
    Sep 7, 2012
Loading...

Share This Page