Thread: Is my C++ compiler broken?

  1. #1
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591

    Is my C++ compiler broken?

    I keep getting this warning (mingw32):
    warning: passing NULL used for non-pointer converting 2 of `void* memset(void*, int, size_t)'
    generated from this line of code:
    Code:
    memset( array, NULL, sizeof(array) );
    Now if NULL expands to 0 or 0L as supposed in C++, and the second arg to memset is an integer (in any sane world), what the heck is my compiler complaining about not being able to be convert NULL to int?!
    Furthermore I get the same problem when using "(int)NULL" to explicit cast, yet it is fine with all of "(long)NULL", "(char) NULL" and "(int)(char)NULL" and "(int)(void*)NULL...!!
    Last edited by @nthony; 10-08-2008 at 08:25 PM.

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    It's not an error; your code will work.

    But NULL is supposed to represent a null pointer. That's what any person expects when they see the keyword NULL. So the compiler is warning you that a passing a null pointer to the second argument of memset does not work as a typical user of the keyword NULL would expect.

    Basically it's enforcing a very very common stylistic policy by means of this warning. Seriously, don't use NULL for anything but pointers. It will confuse anyone trying to read your code. Use 0. I'd even suggest not using NULL at all, but since your compiler is able to give this warning, the argument against it doesn't really apply until you change compilers.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    It probably has NULL defined like this:
    Code:
    #define NULL  (void*)0
    You can verify it by looking in the compiler's header files.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    No, because then it wouldn't be able to mention NULL in the warning. It seems to be treating NULL as a special symbol, like the proposed nullptr. But as long as the above code works, I don't think that qualifies as a standards violation. EDIT: as long as only the warning mechanism is aware of the difference; NULL has to still be treated like a macro, as far as being redefined and the like.
    Last edited by King Mir; 10-08-2008 at 09:43 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Did you #include <cstddef>?

  6. #6
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591
    I had cstdlib included (which should pull in the NULL define), but including cstddef results in the same warning.
    Here is how it's defined in cstddef:
    Code:
    #if defined (_STDDEF_H) || defined (__need_NULL)
    #undef NULL		/* in case <stdio.h> has defined it. */
    #ifdef __GNUG__
    #define NULL __null
    #else   /* G++ */
    #ifndef __cplusplus
    #define NULL ((void *)0)
    #else   /* C++ */
    #define NULL 0
    #endif  /* C++ */
    #endif  /* G++ */
    It must be using something other than the (void *), because that would result in a conversion error.
    Searching google with the warning brings up some problems in gcc flagging improper warnings, so I was wondering if this could have been it.

    The array is an array of pointers, I initialize with NULL to complement that concept (I know initialization is by byte and pointers are usually multi-byte, but it achieves what I want plus servers as a handy reminder). Regardless, using an explicit cast should avoid this warning.... or put another way, the compiler treats (int)NULL as a warning but accepts (long)NULL, odd...

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > memset( array, NULL, sizeof(array) );
    Second param is an int, so just do
    memset( array, 0, sizeof(array) );

    Why are you worrying about how your particular compiler declares NULL?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591
    I'm not, but I am worried that, regardless of its definition, it should be standards-compliant. So an explicit conversion to int flagging a warning, much less a warning where (long)NULL isn't, definitely gets me worried (especially from one of the better-known compilers).

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    If you're ever intending to set an array of pointers to NULL, then it might interest you to know that although assigning zero to a pointer will in fact set the pointer to a null value, a null pointer doesn't necessarily have to be represented by all bits being zero. Thus using a memset to all bits being zero isn't 100% portable.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Also, should NULL be defined as some other value than 0, your code may well fail, as memset, although its second argument is an integer, will set the memory to the BYTE (or char) value of the second argument, not the integer value - so let's say for arguments sake that NULL is defined as 0x12345678 - you would be setting the memory to 0x78, 0x78, 0x78 - so your array would contain 0x78787878, and a comparison "if (array[i] == NULL)" would not work.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by matsp View Post
    Also, should NULL be defined as some other value than 0, your code may well fail, as memset, although its second argument is an integer, will set the memory to the BYTE (or char) value of the second argument, not the integer value - so let's say for arguments sake that NULL is defined as 0x12345678 - you would be setting the memory to 0x78, 0x78, 0x78 - so your array would contain 0x78787878, and a comparison "if (array[i] == NULL)" would not work.
    Yes, indeed. NULL is not required to have a zero value. However, assigning some_pointer = 0 is required to have the same effect as setting that pointer to NULL, and comparing that pointer with NULL is required to yield a true (non-zero in C) result.

    @nthony's compiler is not wrong in giving the warning, but it is not required to give it either.

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Just call the compiler by its name, GCC. It won't hurt anybody.

    Next, the C++ standard merely says:
    The macro NULL is an implementation-defined C++ null-pointer constant in this International Standard
    It doesn't matter what NULL is defined as, as long as the compiler documents it somewhere and it is a valid null pointer constant. GCC defines it to be __nullptr, which (for backwards compatibility) can be converted to the integer 0, but will emit a warning if this is done.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by CornedBee View Post
    Just call the compiler by its name, GCC. It won't hurt anybody.
    Maybe not, but these things vary with gcc version, and the discussion (other than the particular error message) is not compiler specific.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by grumpy
    Yes, indeed. NULL is not required to have a zero value. However, assigning some_pointer = 0 is required to have the same effect as setting that pointer to NULL, and comparing that pointer with NULL is required to yield a true (non-zero in C) result.
    Quote Originally Posted by CornedBee
    It doesn't matter what NULL is defined as, as long as the compiler documents it somewhere and it is a valid null pointer constant. GCC defines it to be __nullptr, which (for backwards compatibility) can be converted to the integer 0, but will emit a warning if this is done.
    A note at the end of the sentence that CornedBee quoted states: "Possible definitions include 0 and 0L, but not (void*)0."

    Furthermore, section 4.10 of the 2003 edition of the C++ Standard states: "A null pointer constant is an integral constant expression rvalue of integer type that evaluates to zero."

    So, if NULL is an implementation defined null pointer constant, and a null pointer constant evaluates to zero, then it seems to me that NULL is required to have a zero value, even if it is not actually the literal 0.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Interesting. This means that GCC would be non-compliant if it didn't allow conversion from __nullptr to int. On the other hand, nothing is preventing it from emitting a warning if __nullptr is used in integer context.

    Of course, we should remember Norman Diamond:
    Just because the standard provides a cliff in front of you, you are not necessarily required to jump off it.
    Last edited by CornedBee; 10-09-2008 at 12:50 PM.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiler Paths...
    By Cobra in forum C++ Programming
    Replies: 5
    Last Post: 09-26-2006, 04:04 AM
  2. C Compiler and stuff
    By pal1ndr0me in forum C Programming
    Replies: 10
    Last Post: 07-21-2006, 11:07 AM
  3. I can't get this new compiler to work.
    By Loduwijk in forum C++ Programming
    Replies: 7
    Last Post: 03-29-2006, 06:42 AM
  4. how to call a compiler?
    By castlelight in forum C Programming
    Replies: 3
    Last Post: 11-22-2005, 11:28 AM
  5. Help With finding a compiler
    By macman in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-15-2005, 08:15 AM