(ArduinoJson) crash trying to pass JsonObject

I think this is probably a generic question about my misunderstanding of references, but it's specifically come up while using the ArduinoJson library.

I got my program succesfully reading JSON from an external source, using the ArduinoJson library to parse it, converting data into the form I need it, and so on.

Having got it roughly working, I then started cleaning it up and moved a bit of code into a function so that I could call it in two places.

The critical piece is a loop over a JsonArray. Originally it was inline in the function that had parsed the JSON data, i.e. (omitting various error checking):

 	float fWidth;

  	DeserializationError error = deserializeJson(doc, jsonText);
        ...
	JsonArray aDims = doc["dimensionsList"].as<JsonArray>();
        ...
 	for (JsonObject repo : aDims) {
 	 	fWidth = repo["width"];
 	 	Serial.println(fWidth);
 	}

... which works fine.

Then I attempted to move the processing of the elements of the array into a function, and it crashes as soon as it tries to access one of the elements of the JsonObject:

  	DeserializationError error = deserializeJson(doc, jsonText);
        ...
	JsonArray aDims = doc["dimensionsList"].as<JsonArray>();
        ...
 	for (JsonObject repo : aDims) {
 	 	printWidth(repo);
 	}
        ...


void printWidth(JsonObject jElement)
{
 	float fWidth;

	fWidth = jElement["width"];		// crashes on this line
 	Serial.println(fWidth);
}

Evidently there is an issue with how I pass the iterator JsonObject into the function - or how I then access the elements of it.

I've read @BenoitB's excellent book, with the very helpful "missing C++ course" chapter; but I didn't see anything which would suggest that this shouldn't work. I've also in desperation tried all the variations of syntax I could imagine, but none worked. I also, since (in the actual code as opposed to the above cut-down one) the secondary function doesn't need to change the values in the JsonObject, tried declaring it as const in the secondary function; no joy.

I don't see why it wouldn't be possible to pass a reference into a function, and then use it in this way... am I wrong? And if not, what am I doing wrong in this syntax?

What happens when you pass the object by reference?

void printWidth(JsonObject& jElement)

Still crash, alas.

what if you do

 	for (JsonObject&& repo : aDims) {
 	 	printWidth(repo);
 	}

and define the function with a reference

void printWidth(JsonObject& jElement) {
   	float fWidth = jElement["width"];
 	Serial.println(fWidth);
}

What does this && syntax

for (JsonObject&& repo : aDims) {

do?

Surely I can't change what the iteration over aDims consists of?

It is an Universal/Forwarding Reference.

We usually actually would let the compiler figure things out and write

for (auto && repo : aDims) {
 	 	printWidth(repo);
 	}

(You could also use only one & probably here.)

The point is that you don’t get a copy of the item accessed by the array notation but a reference to it. Just wondering if that would make any difference

Hi @KellyLH,

The program you shared in your original message should work just fine.
Here is an online demo to prove there is nothing wrong with it: [C++] gcc 4.9.4 - Wandbox

The problem lies probably in the parts you omitted.
Please provide an MCVE.

BTW, thank you very much for purchasing my book :heart:

Best regards,
Benoit

Hi @BenoitB - I'm an idiot! Thank you.

Indeed, I am afraid I cut down the example in my post, rather than in my code; and as you say, there was in fact no problem with passing the JsonObject in that way. The crashing problem was (and is, I am still banging my head against the wall) in what I thought was a perfectly straightforward bit of syntax that was part of the same refactoring. I took it for granted that the problem was in the exotic new syntax that I didn't really understand.

Apologies for wasting your time. Thanks again for the ArduinoJson library, and the book - both are excellent.

Many thanks,

Kelly.