Zero as null pointer constant
-
Hi,
I tried QtCreator 4.7.0-rc1 and since then I get a lot of these warnings:
Warning: zero as null pointer constant
The affected line looks like this:
libraryModels[0]->addItem(LibraryItem("Music","",0,0,false));
The variable libraryModel is defined as
QList<LibraryModel*>
. What is wrong here? I didn't get any warnings until now and it has always worked as expected. -
Hi,
I tried QtCreator 4.7.0-rc1 and since then I get a lot of these warnings:
Warning: zero as null pointer constant
The affected line looks like this:
libraryModels[0]->addItem(LibraryItem("Music","",0,0,false));
The variable libraryModel is defined as
QList<LibraryModel*>
. What is wrong here? I didn't get any warnings until now and it has always worked as expected.This version is still using the older initialization style for unassigned pointers.
The compiler you are using is probably following C++11 standard. Therefore, it gives you a warning (see also this link)
You could set a macro avoiding the output of the warning.
-
Modern C++ offers "nullptr" as a universal null pointer. You should use that instead of zero, because there are some obscure machines that have things like signed pointers where a null pointer is actually something like -1 rather than 0. Using nullptr is also a lot more explicit so it saves you from mixing up a pointer param and an int param. 0 could be valid for either, but if you try to pass nullptr to an int parameter it won't compile. If you put 0 thinking you were passing a null pointer, but it was actually an int parameter, the compiler could never warn you that you were doing something silly.
-
This version is still using the older initialization style for unassigned pointers.
The compiler you are using is probably following C++11 standard. Therefore, it gives you a warning (see also this link)
You could set a macro avoiding the output of the warning.
@koahnig I don't need to suppress the warning I was just wondering if there is something wrong in my code or if QtCreator shows an incorrect warning.
@wrosecrans But the 0 is not meant to be a null pointer. It as an index of the QList variable. I'm not trying to set or use a null pointer. The zeroes where this warning is displayed are always used as an index and so the 0 is correct.
-
Hi,
Why are you using a pointer to a QList ?
The code you wrote doesn’t do what you think. You’re not accessing the first element of your list.
-
@koahnig I don't need to suppress the warning I was just wondering if there is something wrong in my code or if QtCreator shows an incorrect warning.
@wrosecrans But the 0 is not meant to be a null pointer. It as an index of the QList variable. I'm not trying to set or use a null pointer. The zeroes where this warning is displayed are always used as an index and so the 0 is correct.
@vlada said in Zero as null pointer constant:
But the 0 is not meant to be a null pointer. It as an index of the QList variable.
There are 3 zeroes in your affected line. The first one is your index -- what about the other two?
@SGaist said in Zero as null pointer constant:
Why are you using a pointer to a QList ?
I think it's just a forum formatting issue.
@vlada, to confirm: Is libraryModels
QList<LibraryModel*>
orQList<LibraryModel>*
? -
@SGaist I'm not trying to use a pointer to QList. My intention is to do a list a pointers. Then I'm trying to call a function of the first object (class). I'll put some more of my code to explain that:
QList<LibraryModel*> libraryModels; for (int i=0; i<5; i++) { libraryModels << new LibraryModel(); qmlLibraryModel.append(QVariant::fromValue(libraryModels[i])); }
@JKSH The other two zeroes are just integer parameters passed as arguments to the object constructor:
LibraryItem::LibraryItem(const QString &text, const QString &image, const QString &track, const int &id, const bool &checked) : m_text(text), m_image(image), m_track(track), m_id(id), m_checked(checked) { }
As can be seen from the first code sample, the former variant is correct. The intention was to create list of pointers and access the pointers by it's index.
-
@SGaist I'm not trying to use a pointer to QList. My intention is to do a list a pointers. Then I'm trying to call a function of the first object (class). I'll put some more of my code to explain that:
QList<LibraryModel*> libraryModels; for (int i=0; i<5; i++) { libraryModels << new LibraryModel(); qmlLibraryModel.append(QVariant::fromValue(libraryModels[i])); }
@JKSH The other two zeroes are just integer parameters passed as arguments to the object constructor:
LibraryItem::LibraryItem(const QString &text, const QString &image, const QString &track, const int &id, const bool &checked) : m_text(text), m_image(image), m_track(track), m_id(id), m_checked(checked) { }
As can be seen from the first code sample, the former variant is correct. The intention was to create list of pointers and access the pointers by it's index.
@vlada said in Zero as null pointer constant:
@JKSH The other two zeroes are just integer parameters
No. They are const references to int and bool:
LibraryItem::LibraryItem(const QString &text, const QString &image, const QString &track, const int &id, const bool &checked)
That just does not make sense. Both int and bool are better passed by value:
LibraryItem::LibraryItem(const QString &text, const QString &image, const QString &track, int id, bool checked)
Regards
-
@vlada said in Zero as null pointer constant:
@JKSH The other two zeroes are just integer parameters
No. They are const references to int and bool:
LibraryItem::LibraryItem(const QString &text, const QString &image, const QString &track, const int &id, const bool &checked)
That just does not make sense. Both int and bool are better passed by value:
LibraryItem::LibraryItem(const QString &text, const QString &image, const QString &track, int id, bool checked)
Regards
@aha_1980 Thank you. I was blind and looking for the problem at a wrong place. The warning was caused becasued I called the constructor with 0, but it should have been "0", because the variable is a string.
Also thank you for the tips regarding passing references to int and bool. You are right it doesn't make any sense.
-
Modern C++ offers "nullptr" as a universal null pointer. You should use that instead of zero, because there are some obscure machines that have things like signed pointers where a null pointer is actually something like -1 rather than 0. Using nullptr is also a lot more explicit so it saves you from mixing up a pointer param and an int param. 0 could be valid for either, but if you try to pass nullptr to an int parameter it won't compile. If you put 0 thinking you were passing a null pointer, but it was actually an int parameter, the compiler could never warn you that you were doing something silly.
@wrosecrans
[Since the OP is not looking for further answers in this thread...]because there are some obscure machines [...] where a null pointer is actually something like -1 rather than 0.
Really? I thought however you dressed a "null" pointer up in C/C++, its underlying value has to be 0, no? Else you'd also break so much existing code.
-
@wrosecrans
[Since the OP is not looking for further answers in this thread...]because there are some obscure machines [...] where a null pointer is actually something like -1 rather than 0.
Really? I thought however you dressed a "null" pointer up in C/C++, its underlying value has to be 0, no? Else you'd also break so much existing code.
Mostly pretty odd archaic machines were the only ones with non-zero Null. But it's technically valid to have it be -1 if you invented some modern strange machine with signed pointers. (Though there is a lot more inertia and existing code that requires a zero Null now than there was in the early 80's!)
http://c-faq.com/null/machexamp.html
I dunno exactly how the vendor compilers on Dreamcast handled Null, but the memory map looped around on itself repeatedly, using some of the bits as stuff like cache control.
http://mc.pp.se/dc/memory.html
So you could have a pointer like 1010000000000000000000000000000 that refers to physical address 0 and use something like that as a null pointer if you were a bit wrong in the head.
I think C99 was when 0 was required to be a portable expression of Null. So it's unlikely that you would run into such weirdness going forward, but there is probably still plenty of code from the old days still in service that predates the guarantee. (Whether that code accounts for the rules when it was made or not.)
-
Mostly pretty odd archaic machines were the only ones with non-zero Null. But it's technically valid to have it be -1 if you invented some modern strange machine with signed pointers. (Though there is a lot more inertia and existing code that requires a zero Null now than there was in the early 80's!)
http://c-faq.com/null/machexamp.html
I dunno exactly how the vendor compilers on Dreamcast handled Null, but the memory map looped around on itself repeatedly, using some of the bits as stuff like cache control.
http://mc.pp.se/dc/memory.html
So you could have a pointer like 1010000000000000000000000000000 that refers to physical address 0 and use something like that as a null pointer if you were a bit wrong in the head.
I think C99 was when 0 was required to be a portable expression of Null. So it's unlikely that you would run into such weirdness going forward, but there is probably still plenty of code from the old days still in service that predates the guarantee. (Whether that code accounts for the rules when it was made or not.)
@wrosecrans
Being a student of languages, forgive my interest, but I'm actually surprised you're saying the non-0-null would date back to early C days. If anything I would think in those days it had to be zero.C (can't say for C++) programs can & do contain:
struct list *p = start; while (p) { p = p->next; }
Note the test is
while(p)
, and notwhile (p != NULL)
. Now, in order for that to work, surely the "null" pointer has to have value 0?I do not dispute what you are saying about signed pointers or even funny memory layout/addresses. But I remain to be convinced that "null" has ever been able to have value anything other than 0 in C. (K&R explicitly explain that pointers & integers are not normally interchangeable, but that zero is the sole exception, and that
NULL
"is often used in place of zero".) Can you point to any actual example where this was not the case? -
@wrosecrans
Being a student of languages, forgive my interest, but I'm actually surprised you're saying the non-0-null would date back to early C days. If anything I would think in those days it had to be zero.C (can't say for C++) programs can & do contain:
struct list *p = start; while (p) { p = p->next; }
Note the test is
while(p)
, and notwhile (p != NULL)
. Now, in order for that to work, surely the "null" pointer has to have value 0?I do not dispute what you are saying about signed pointers or even funny memory layout/addresses. But I remain to be convinced that "null" has ever been able to have value anything other than 0 in C. (K&R explicitly explain that pointers & integers are not normally interchangeable, but that zero is the sole exception, and that
NULL
"is often used in place of zero".) Can you point to any actual example where this was not the case?@JonB said in Zero as null pointer constant:
Note the test is while(p), and not while (p != NULL). Now, in order for that to work, surely the "null" pointer has to have value 0?
That worked on like 99.9% of the systems ever made, and eventually became a fact of the standard in C99, but nope. There were actually some funky old systems where that wouldn't work as expected and you really were supposed to compare to whatever NULL was defined as rather than 0. On some systems you need to be able to access address zero as a place where good useful bits of information were stored.
-
@JonB said in Zero as null pointer constant:
Note the test is while(p), and not while (p != NULL). Now, in order for that to work, surely the "null" pointer has to have value 0?
That worked on like 99.9% of the systems ever made, and eventually became a fact of the standard in C99, but nope. There were actually some funky old systems where that wouldn't work as expected and you really were supposed to compare to whatever NULL was defined as rather than 0. On some systems you need to be able to access address zero as a place where good useful bits of information were stored.
@wrosecrans Interesting! Thanks for the comment. :)