on C11+ and newer compilers, the = operator does not behave as expected. The code is listed below
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) |
|
JSONVar& JSONVar::operator=(JSONVar&& v) |
|
{ |
|
cJSON* tmp; |
|
|
|
// swap _json |
|
tmp = _json; |
|
_json = v._json; |
|
v._json = tmp; |
|
|
|
// swap parent |
|
tmp = _parent; |
|
_parent = v._parent; |
|
v._parent = tmp; |
|
|
|
return *this; |
|
} |
|
#endif |
This overload is invoked when a JSONVar is set equal to another JSONVar by reference like so:
JSONVar a const
char input[] = "{'foo':{'bar': '42'}}";
JSONVar a = JSON.parse(input);
JSONVar b = a["foo"];
Serial.print("b['foo']: ");
Serial.println(b["foo"]);
result:
I see a few things wrong with this:
First, swapping the c_json pointers in the JSONVar container does nothing as the linked list is all stored in the c_json structs. The JSONVar object only is created on the fly when requested via the [] operator, and destroyed when out of scope. See below:
JSONVar JSONVar::operator[](const char* key)
{
Serial.println(key);
if (!cJSON_IsObject(_json)) {
replaceJson(cJSON_CreateObject());
}
cJSON* json = cJSON_GetObjectItemCaseSensitive(_json, key);
if (json == NULL) {
json = cJSON_AddNullToObject(_json, key);
}
return JSONVar(json, _json);
}
Second, the intent of the code in the C11+ rvalue = overloaded operator is to swap the two objects instead of copy. Why? This is not the same behavior as in older compilers and is not the same behavior if the = operator is used on a JSONVar object directly without referencing. This is is incredibly confusing to have an object be copied in one situation, but then be swapped in a different situation. In my opinion the = operator should always copy, regardless if an lvalue or rvalue is passed.
on C11+ and newer compilers, the
=operator does not behave as expected. The code is listed belowArduino_JSON/src/JSONVar.cpp
Lines 244 to 261 in ea843a9
This overload is invoked when a
JSONVaris set equal to anotherJSONVarby reference like so:result:
I see a few things wrong with this:
First, swapping the
c_jsonpointers in theJSONVarcontainer does nothing as the linked list is all stored in thec_jsonstructs. TheJSONVarobject only is created on the fly when requested via the[]operator, and destroyed when out of scope. See below:Second, the intent of the code in the C11+ rvalue
=overloaded operator is to swap the two objects instead of copy. Why? This is not the same behavior as in older compilers and is not the same behavior if the=operator is used on aJSONVarobject directly without referencing. This is is incredibly confusing to have an object be copied in one situation, but then be swapped in a different situation. In my opinion the=operator should always copy, regardless if an lvalue or rvalue is passed.