Upgrading some legacy code, I’ve started getting “warning: passing NULL to non-pointer argument 1 of ‘Identifier::Identifier(int)’ [-Wconversion-null]” messages from g++. Mostly this is good, but it doesn’t seem to take classes with multiple constructors into account.
For example, take this test code:
#include <stdio.h>
class Identifier
{
private:
int m_iID;
public:
Identifier(const char* p_c) { m_iID = p_c ? p_c[0] : 0; }
Identifier(int i) { m_iID = i; }
};
int main(int argc, char* argv[])
{
Identifier* p_ID = new Identifier(NULL);
return 0;
}
(Please ignore what the constructors actually do, this is just an illustration of the issue. For context, the code in question is a class that stores an identifier in the form of a hash value. The constructors can either take a string to convert to a hash, or the hash value directly.)
The “new” statement on the third to last line throws this warning. The thing that is puzzling me is that g++ is apparently assuming that it needs to use the Identifier(int i) constructor, and ignores the Identifier(const char* p_c) constructor, which is a pointer.
Note that changing the ints to unsigned ints causes an ambiguity error instead, this being a 32-bit system.
I know specifying -Wno-conversion-null would fix the problem, as would passing 0 or explicitly casting NULL to const char*. But I’m curious as to why the seemingly valid constructor is being ignored. Plus, I’d like to avoid a massive search-and-replace job whilst keeping the warning active.
At least on this CentOS box, NULL is defined in
linux/stddef.h:As such, NULL in C++ is an integer; therefore the compiler chooses the
intconstructor by default and gives you the warning you’re seeing.