checking if pointer is NULL allowed?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Clever Monkey

    #16
    Re: checking if pointer is NULL allowed?

    Ben Pfaff wrote:
    Alef.Veld@gmail .com writes:
    >
    >Well, if it is not pointing to anything anyway, couldn't my compiler
    >just printf out "null". And i swear i thought i have seen this.
    >
    Are you confusing dereferencing an invalid pointer with passing a
    null pointer to printf in place of a pointer argument? Both are
    undefined behavior. The former is usually difficult or expensive
    for an implementation to detect, whereas the latter is handled
    gracefully by better-quality C libraries (which often do print
    "null" or "(null)").
    It is common practice in many shops I've worked at to have a function or
    macro used in debugging routines that can take a pointer and return the
    pointer or "null", depending on if the pointer is valid to dereference
    or not.

    Comment

    • Ben Pfaff

      #17
      Re: checking if pointer is NULL allowed?

      Clever Monkey <clvrmnky.inval id@hotmail.com. invalidwrites:
      It is common practice in many shops I've worked at to have a function
      or macro used in debugging routines that can take a pointer and return
      the pointer or "null", depending on if the pointer is valid to
      dereference or not.
      What kind of code do you work on?
      --
      "To get the best out of this book, I strongly recommend that you read it."
      --Richard Heathfield

      Comment

      • santosh

        #18
        Re: checking if pointer is NULL allowed?

        Clever Monkey wrote:
        Ben Pfaff wrote:
        Alef.Veld@gmail .com writes:
        Well, if it is not pointing to anything anyway, couldn't my compiler
        just printf out "null". And i swear i thought i have seen this.
        Are you confusing dereferencing an invalid pointer with passing a
        null pointer to printf in place of a pointer argument? Both are
        undefined behavior. The former is usually difficult or expensive
        for an implementation to detect, whereas the latter is handled
        gracefully by better-quality C libraries (which often do print
        "null" or "(null)").
        >
        It is common practice in many shops I've worked at to have a function or
        macro used in debugging routines that can take a pointer and return the
        pointer or "null", depending on if the pointer is valid to dereference
        or not.
        Maybe, but that's not possible in standard C.

        Comment

        • Keith Thompson

          #19
          Re: checking if pointer is NULL allowed?

          Alef.Veld@gmail .com writes:
          Ben Pfaff wrote:
          Alef.V...@gmail .com writes:
          >Well, if it is not pointing to anything anyway, couldn't my compiler
          >just printf out "null". And i swear i thought i have seen this.
          >
          Are you confusing dereferencing an invalid pointer with passing a
          null pointer to printf in place of a pointer argument?
          >
          I'm not quite sure what you mean here. I just wanted to know why i
          sometimes noticed that printf printed out a nice "null" when i gave it
          a pointer i explicitly set to NULL. I'm not talking about 'bad'
          pointers here. But now i have my answer, the better libc libraries do
          print this out. Thanks everyone.
          >
          Surely all the OP needed to know is that inspecting the value of a
          pointer
          does not constitute "dereferenc ing" it?
          >
          No. I know that :-)
          >
          And oddly enough, there may be something wrong with the following,
          understandble, mistake:
          /*let's print the value of the NULL pointer*/
          printf("%p\n", NULL);
          --
          jay
          >
          Would this not print out something akin to 0x0?
          It's very difficult to tell which parts of your followup are quoted
          from previous articles, since you didn't use "" markers. You're
          also missing some attribution lines, so it's hard to tell who you're
          quoting. Google Groups does these for you automatically, so I'm not
          sure what went wrong here.

          jay wrote the last bit:
          | And oddly enough, there may be something wrong with the following,
          | understandble, mistake:
          | /*let's print the value of the NULL pointer*/
          | printf("%p\n", NULL);

          One legal definition for the NULL macro is just 0, which is a null
          pointer constant, but is only treated as a pointer in the right
          context. Since printf is a variadic function (it takes a variable
          number and type(s) of arguments), the compiler doesn't know that that
          argument is supposed to be a pointer; it just passes a value of type
          int with value 0, which may or may not look like a null pointer by the
          time printf sees it.

          The correct way to print the value of a null pointer is:

          printf("%p\n", (void*)NULL);

          The output is implementation-defined.

          Section 5 of the comp.lang.c FAQ, <http://www.c-faq.com/has a lot
          more information on this.

          --
          Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

          Comment

          • tedu

            #20
            Re: checking if pointer is NULL allowed?

            On Jan 25, 9:23 am, "santosh" <santosh....@gm ail.comwrote:
            Clever Monkey wrote:
            It is common practice in many shops I've worked at to have a function or
            macro used in debugging routines that can take a pointer and return the
            pointer or "null", depending on if the pointer is valid to dereference
            or not.
            >
            Maybe, but that's not possible in standard C.
            why not?

            Comment

            • Richard Tobin

              #21
              Re: checking if pointer is NULL allowed?

              In article <1169768146.763 494.270880@a75g 2000cwd.googleg roups.com>,
              tedu <tu@zeitbombe.o rgwrote:
              It is common practice in many shops I've worked at to have a function or
              macro used in debugging routines that can take a pointer and return the
              pointer or "null", depending on if the pointer is valid to dereference
              or not.
              >Maybe, but that's not possible in standard C.
              >why not?
              You can tell whether it's null (which I suspect is what was meant) but
              you can't check that it's "valid to dereference" - it might be a
              free()ed pointer for example.

              -- Richard



              --
              "Considerat ion shall be given to the need for as many as 32 characters
              in some alphabets" - X3.4, 1963.

              Comment

              • Chris Dollin

                #22
                Re: checking if pointer is NULL allowed?

                tedu wrote:
                On Jan 25, 9:23 am, "santosh" <santosh....@gm ail.comwrote:
                >Clever Monkey wrote:
                It is common practice in many shops I've worked at to have a function or
                macro used in debugging routines that can take a pointer and return the
                pointer or "null", depending on if the pointer is valid to dereference
                or not.
                >>
                >Maybe, but that's not possible in standard C.
                >
                why not?
                There's no way to find out if "the pointer is valid to dereference
                or not".

                However you try and construct one, you will find undefined
                behaviour lying in wait.

                (A /specific implementation/ might offer such a function, although
                I can't see it being both reliable and cheap.)

                --
                Chris "electric hedgehog" Dollin
                "Our future looks secure, but it's all out of our hands"
                - Magenta, /Man and Machine/

                Comment

                • Richard Heathfield

                  #23
                  Re: checking if pointer is NULL allowed?

                  Chris Dollin said:
                  tedu wrote:
                  >
                  >On Jan 25, 9:23 am, "santosh" <santosh....@gm ail.comwrote:
                  >>Clever Monkey wrote:
                  >It is common practice in many shops I've worked at to have a function
                  >or macro used in debugging routines that can take a pointer and return
                  >the pointer or "null", depending on if the pointer is valid to
                  >dereference or not.
                  >>>
                  >>Maybe, but that's not possible in standard C.
                  >>
                  >why not?
                  >
                  There's no way to find out if "the pointer is valid to dereference
                  or not".
                  Well, you know that it isn't valid to deref if it's NULL. So the trick here
                  is to ensure that all your pointers are *either* valid *or* NULL,
                  throughout your code. Change the paradigm. Instead of thinking "how do I
                  detect whether I've screwed up" (which is generally a good thing to think,
                  but in this case turns out to be impractical in portable code), think "what
                  coding habits can I adopt that minimise the risk of screwing up in the
                  first place?"

                  --
                  Richard Heathfield
                  "Usenet is a strange place" - dmr 29/7/1999

                  email: rjh at the above domain, - www.

                  Comment

                  • =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=

                    #24
                    Re: checking if pointer is NULL allowed?

                    Keith Thompson wrote:
                    Alef.Veld@gmail .com writes:
                    Ben Pfaff wrote:
                    Alef.V...@gmail .com writes:
                    >>Well, if it is not pointing to anything anyway, couldn't my compiler
                    >>just printf out "null". And i swear i thought i have seen this.
                    Are you confusing dereferencing an invalid pointer with passing a
                    null pointer to printf in place of a pointer argument?
                    I'm not quite sure what you mean here. I just wanted to know why i
                    sometimes noticed that printf printed out a nice "null" when i gave it
                    a pointer i explicitly set to NULL. I'm not talking about 'bad'
                    pointers here. But now i have my answer, the better libc libraries do
                    print this out. Thanks everyone.

                    Surely all the OP needed to know is that inspecting the value of a
                    pointer
                    does not constitute "dereferenc ing" it?

                    No. I know that :-)

                    And oddly enough, there may be something wrong with the following,
                    understandble, mistake:
                    /*let's print the value of the NULL pointer*/
                    printf("%p\n", NULL);
                    --
                    jay

                    Would this not print out something akin to 0x0?
                    >
                    It's very difficult to tell which parts of your followup are quoted
                    from previous articles, since you didn't use "" markers. You're
                    also missing some attribution lines, so it's hard to tell who you're
                    quoting. Google Groups does these for you automatically, so I'm not
                    sure what went wrong here.
                    He replied to two messages with one. Google quoted Ben Pfaff's message,
                    with an attribution line, and "" markers. He added jaysome's message,
                    with a simple copy and paste.
                    jay wrote the last bit:
                    | And oddly enough, there may be something wrong with the following,
                    | understandble, mistake:
                    | /*let's print the value of the NULL pointer*/
                    | printf("%p\n", NULL);
                    >
                    One legal definition for the NULL macro is just 0, which is a null
                    pointer constant, but is only treated as a pointer in the right
                    context. Since printf is a variadic function (it takes a variable
                    number and type(s) of arguments), the compiler doesn't know that that
                    argument is supposed to be a pointer; it just passes a value of type
                    int with value 0, which may or may not look like a null pointer by the
                    time printf sees it.
                    >
                    The correct way to print the value of a null pointer is:
                    >
                    printf("%p\n", (void*)NULL);
                    >
                    The output is implementation-defined.
                    I would (and did) use (void *) 0. (void *) NULL is valid in this
                    context, but not in some others where (void *) 0 is, because it is not
                    necessarily a null pointer constant. All it is sure to be is a constant
                    null pointer.
                    Section 5 of the comp.lang.c FAQ, <http://www.c-faq.com/has a lot
                    more information on this.

                    Comment

                    • =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=

                      #25
                      Re: checking if pointer is NULL allowed?

                      Richard Heathfield wrote:
                      Chris Dollin said:
                      >
                      tedu wrote:
                      On Jan 25, 9:23 am, "santosh" <santosh....@gm ail.comwrote:
                      >Clever Monkey wrote:
                      It is common practice in many shops I've worked at to have a function
                      or macro used in debugging routines that can take a pointer and return
                      the pointer or "null", depending on if the pointer is valid to
                      dereference or not.
                      >>
                      >Maybe, but that's not possible in standard C.
                      >
                      why not?
                      There's no way to find out if "the pointer is valid to dereference
                      or not".
                      >
                      Well, you know that it isn't valid to deref if it's NULL
                      and not one past the last element of an array.

                      Comment

                      • jaysome

                        #26
                        Re: checking if pointer is NULL allowed?

                        On Fri, 26 Jan 2007 08:33:08 +0000, Richard Heathfield
                        <rjh@see.sig.in validwrote:
                        >Chris Dollin said:
                        >
                        >tedu wrote:
                        >>
                        >>On Jan 25, 9:23 am, "santosh" <santosh....@gm ail.comwrote:
                        >>>Clever Monkey wrote:
                        >>It is common practice in many shops I've worked at to have a function
                        >>or macro used in debugging routines that can take a pointer and return
                        >>the pointer or "null", depending on if the pointer is valid to
                        >>dereference or not.
                        >>>>
                        >>>Maybe, but that's not possible in standard C.
                        >>>
                        >>why not?
                        >>
                        >There's no way to find out if "the pointer is valid to dereference
                        >or not".
                        >
                        >Well, you know that it isn't valid to deref if it's NULL. So the trick here
                        >is to ensure that all your pointers are *either* valid *or* NULL,
                        >throughout your code. Change the paradigm. Instead of thinking "how do I
                        >detect whether I've screwed up" (which is generally a good thing to think,
                        >but in this case turns out to be impractical in portable code), think "what
                        >coding habits can I adopt that minimise the risk of screwing up in the
                        >first place?"
                        Yes.

                        And thinking about both gives you the best of said both worlds.
                        Everyone screws up--so every smart person, process and tool you can
                        throw at these two pillars of your paradigm is worth it, and arguably
                        even priceless.

                        Regards
                        --
                        jay

                        Comment

                        • jaysome

                          #27
                          Re: checking if pointer is NULL allowed?

                          On Fri, 26 Jan 2007 08:25:36 +0000, Chris Dollin <chris.dollin@h p.com>
                          wrote:

                          [snip]
                          >(A /specific implementation/ might offer such a function, although
                          I can't see it being both reliable and cheap.)
                          It depends on your definitions of "reliable" and "cheap".

                          On one specific implementation I know of:

                          #include <stdio.h>
                          #include <time.h>
                          #include <windows.h>
                          #define NUM 0x4000
                          #define NUM_RUNS 10
                          int main(void)
                          {
                          unsigned nn;
                          clock_t c1, c2;
                          for ( nn = 0; nn < NUM_RUNS; nn++ )
                          {
                          int ii, num_bad = 0;
                          c1 = clock();
                          for ( ii = 0; ii < NUM; ii++ )
                          {
                          num_bad += IsBadReadPtr((v oid*)ii, 1) != 0;//lint !e514
                          }
                          c2 = clock();
                          printf("tested: 0x%04X; bad: 0x%04X\n", NUM, num_bad);
                          printf("%.1f microseconds per call\n",
                          (c2 - c1) / (double)CLOCKS_ PER_SEC / NUM * 1e6);
                          }
                          return 0;
                          }

                          Output:

                          tested: 0x4000; bad: 0x4000
                          8.5 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          9.5 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          8.6 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          8.6 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          8.5 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          8.6 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          9.5 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          8.6 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          8.5 microseconds per call
                          tested: 0x4000; bad: 0x4000
                          8.6 microseconds per call
                          Press any key to continue

                          Regards
                          --
                          jay

                          Comment

                          • Chris Dollin

                            #28
                            Re: checking if pointer is NULL allowed?

                            jaysome wrote:
                            On Fri, 26 Jan 2007 08:25:36 +0000, Chris Dollin <chris.dollin@h p.com>
                            wrote:
                            >
                            [snip]
                            >
                            >>(A /specific implementation/ might offer such a function, although
                            >I can't see it being both reliable and cheap.)
                            >
                            It depends on your definitions of "reliable" and "cheap".
                            Surely. I meant by "reliable" "gives the right answer so often it's
                            worth using" and by "cheap" "it's performance doesn't cripple the
                            application". Still room for manouever, of course.
                            >
                            On one specific implementation I know of:
                            >
                            #include <stdio.h>
                            #include <time.h>
                            #include <windows.h>
                            #define NUM 0x4000
                            #define NUM_RUNS 10
                            int main(void)
                            {
                            unsigned nn;
                            clock_t c1, c2;
                            for ( nn = 0; nn < NUM_RUNS; nn++ )
                            {
                            int ii, num_bad = 0;
                            c1 = clock();
                            for ( ii = 0; ii < NUM; ii++ )
                            {
                            num_bad += IsBadReadPtr((v oid*)ii, 1) != 0;//lint !e514
                            }
                            c2 = clock();
                            printf("tested: 0x%04X; bad: 0x%04X\n", NUM, num_bad);
                            printf("%.1f microseconds per call\n",
                            (c2 - c1) / (double)CLOCKS_ PER_SEC / NUM * 1e6);
                            }
                            return 0;
                            }
                            >
                            Output:
                            >
                            tested: 0x4000; bad: 0x4000
                            8.5 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            9.5 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            8.6 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            8.6 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            8.5 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            8.6 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            9.5 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            8.6 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            8.5 microseconds per call
                            tested: 0x4000; bad: 0x4000
                            8.6 microseconds per call
                            Press any key to continue
                            8 microseconds per call I'd put in the non-cheap category, assuming
                            the machine is of the order of a GHz: it's taken about 8000 instructions
                            to do that test.

                            For reliability I'd want to check things like:

                            assertTrue( SIZE 0 );
                            char *spoo = malloc( SIZE );
                            assertTrue( canDereference( spoo ) );
                            assertFalse( canDereference( spoo + SIZE ) );
                            free( spoo );
                            assertFalse( canDereference( spoo ) );

                            and

                            int *broken( int arg ) { return &arg; }

                            assertFalse( canDereference( broken( 17 ) ) );

                            but it's possible I'm being too picky for the Clever Monkey's
                            context. (Mind you, I really do want to check that not only
                            is it legal to dereference something, but that it's mine to
                            dereference and not some random address taken at random out
                            of a random hat coloured a random shade of red.)

                            --
                            Chris "electric hedgehog" Dollin
                            Meaning precedes definition.

                            Comment

                            • Chris Dollin

                              #29
                              Re: checking if pointer is NULL allowed?

                              Chris Dollin wrote:
                              jaysome wrote:
                              >
                              >On Fri, 26 Jan 2007 08:25:36 +0000, Chris Dollin <chris.dollin@h p.com>
                              >wrote:
                              >>
                              >[snip]
                              >>
                              >>>(A /specific implementation/ might offer such a function, although
                              >>I can't see it being both reliable and cheap.)
                              >>
                              >It depends on your definitions of "reliable" and "cheap".
                              >
                              Surely. I meant by "reliable" "gives the right answer so often it's
                              worth using" and by "cheap" "it's performance doesn't cripple the
                              application". Still room for manouever, of course.
                              .... and not forgetting that the context described was for /debugging/,
                              where it's more like "right often enough to spot bugs" and "doesn't
                              make debugging ridiculously slow".

                              Richard H's approach of "program in such a way that you don't need
                              to ask those kinds of questions [1]" seems ... useful.

                              [1] "Hardly ever" [2]

                              [2] But maybe often enough that you can remember what to do when
                              you've made a really subtle mistake.

                              --
                              Chris "electric hedgehog" Dollin
                              A rock is not a fact. A rock is a rock.

                              Comment

                              • Flash Gordon

                                #30
                                Re: checking if pointer is NULL allowed?

                                Harald van Dijk wrote, On 26/01/07 08:35:
                                Keith Thompson wrote:
                                <snip>
                                >The correct way to print the value of a null pointer is:
                                >>
                                > printf("%p\n", (void*)NULL);
                                >>
                                >The output is implementation-defined.
                                >
                                I would (and did) use (void *) 0. (void *) NULL is valid in this
                                context, but not in some others where (void *) 0 is, because it is not
                                necessarily a null pointer constant. All it is sure to be is a constant
                                null pointer.
                                In what context would "(void *)NULL" be invalid but "(void *)0" valid? I
                                can't think of any since since "(void *)NULL" will expand to either
                                "(void *)constant-expression-evaluating-to-0" or "(void *)(void
                                *)constant-expression-evaluating-to-0" and the cast from void* to void*
                                does no harm. Perhaps you where thinking of NULL on its own is not valid
                                in all contexts where (void *)0 is?
                                --
                                Flash Gordon

                                Comment

                                Working...