Why can’t I use NULL
?
This article explains why you cannot use the traditional NULL
value with ArduinoJson.
The problem with NULL
As I explained in the article Why C++ programmers don’t use NULL?, C++ defines NULL
like that:
#define NULL 0
As you can see, NULL
is not a pointer: it’s an integer.
So, when you write NULL
in your program, all ArduinoJson sees is a 0
.
Example with serialization
Suppose you wrote the following program:
StaticJsonDocument<128> doc;
doc["value"] = NULL;
serializeJson(doc, Serial);
You probably expect to see the following line in the Serial Monitor:
{"value":null}
However, since NULL
is really 0
, you’ll see this instead:
{"value":0}
Example with deserialization
Suppose you have the following input:
{"a":0,"b":null}
Take the following program:
StaticJsonDocument<128> doc;
deserializeJson(doc, input);
if (doc["a"] == NULL)
Serial.println("a == null");
else
Serial.println("a != null");
if (doc["b"] == NULL)
Serial.println("b == null");
else
Serial.println("b != null");
If you run this program, you’ll get the following output in the Serial Monitor:
a == null
b != null
In other words, you’ll get the exact opposite of what you expected.
The solution
As I explained in the article Why C++ programmers don’t use NULL?, the best solution is to replace NULL
with the keyword nullptr
introduced in C++11.
Because nullptr
has a dedicated type (it’s a pointer, not an int
), ArduinoJson understands what you mean and implements the expected behavior.
Example with serialization
Suppose we upgrade our previous example like this:
StaticJsonDocument<128> doc;
doc["value"] = nullptr;
serializeJson(doc, Serial);
As expected, the program prints the following line in the Serial Monitor:
{"value":null}
Example with deserialization
Suppose you still have the following input:
{"a":0,"b":null}
We can upgrade the original program like this:
StaticJsonDocument<128> doc;
deserializeJson(doc, input);
if (doc["a"] == nullptr)
Serial.println("a == null");
else
Serial.println("a != null");
if (doc["b"] == nullptr)
Serial.println("b == null");
else
Serial.println("b != null");
As expected, you’ll see the following lines in the Serial Monitor:
a != null
b == null
When C++11 is not available
If your compiler doesn’t support nullptr
, you can use one of the two following workarounds.
Option 1: use isNull()
You can use JsonVariant::isNull()
to test if a value is null:
if (doc["a"].isNull())
Serial.println("a == null");
else
Serial.println("a != null");
Option 2: use a null pointer
To insert null
in a JSON document, you must pass a pointer.
Even if nullptr
is not available, you can still pass a null pointer like this:
doc["value"] = (char*)0;
Alternatively, you can define your own null pointer constant like this:
const char* const null = 0;
doc["value"] = null;
See also
- Chapter “The Missing C++ Course” in Mastering ArduinoJson