What's the difference between these?

Hi all,

just curious about this

consider these two lines of code which will produce the same result in a function:

Blockquote
if ((un=="Me")&&(op=="Th")) {return "test";}
if ((op=="Th")&&(un=="Me")) {return "test";}

see anything wrong? OK, well the first line compiles ok the second throws up this:

Blockquote D:\Projects\Programing\Arduino\Boxford\BoxfordRA7855_encoder_update\BoxfordRA7855_encoder_update.ino: In function 'void setup()':
BoxfordRA7855_encoder_update:120:14: error: 'setPresets' was not declared in this scope
setPresets(); //sets machining presets, code in preset unit
^
D:\Projects\Programing\Arduino\Boxford\BoxfordRA7855_encoder_update\Menu.ino: In function 'void mainMenu(int)':
Menu:29:44: error: 'getPreset' was not declared in this scope
case 13: num1=getPreset(num1,LOW);
^
D:\Projects\Programing\Arduino\Boxford\BoxfordRA7855_encoder_update\presets.ino: At global scope:
presets:14:1: error: expected declaration before '}' token
}
^
'setPresets' was not declared in this scope

Which is what I'd expect to see if I'd missed out a brace or had one to many braces, HOWEVER if I add a comment after the second line

Blockquote if ((op=="Th")&&(un=="Me")) {return "test";} //this does not compile

it compiles ok, am I doing something stupid or is this a "glitch". As the first line compiles ok I'll use that but it's not an answer just a work around.

Post code, all of it, in code tags.
Post error messages. All of them

That is all the error messages

...and the code?

Ok, so you think there might be something else in my code that would cause one off those lines to compile and the other to not compile even though they do exactly the same thing just in a different order? I don't want to post all the code here, there is a lot of it(6 pages) so I will write a small test script. if that produces the same result then then I'll post it, if not then I have an issue elsewhere.

For instance, we don't know the types of "un" and "op." If they're not both "Strings", then neither line is likely to do what you expect. One of them MIGHT luck out into being optimized in a way that prevents the other comparison from causing an error.

And we don't know what is around the 'setPresets' function that it's complaining about.

Or whether "op" or "un" has some unfortunate macro definition.

Ideally, you would edit your program down to a smaller example that still exhibits the problem, but having "all the code" is better than nothing.

As you said, the lines SHOULD behave identically.

Yes I appreciate your comments, I've just written a quick test script

typedef struct{String op;String unit;String vl;float v;}preset_record_type;
preset_record_type presets[72];

String op;
String un;



void setup() {
 
  presets[1].op="Fe";presets[1].unit="Me";presets[1].vl="0.050";presets[1].v=0.050;
  presets[2].op="Fe";presets[2].unit="Me";presets[2].vl="0.070";presets[2].v=0.070;
  presets[3].op="Fe";presets[3].unit="Me";presets[3].vl="0.100";presets[3].v=0.100;
  presets[4].op="Fe";presets[4].unit="Me";presets[4].vl="0.125";presets[4].v=0.125;
  presets[5].op="Fe";presets[5].unit="Me";presets[5].vl="0.150";presets[5].v=0.150;
  presets[6].op="Fe";presets[6].unit="Me";presets[6].vl="0.175";presets[6].v=0.175;
  presets[7].op="Fe";presets[7].unit="Me";presets[7].vl="0.200";presets[7].v=0.200;
  presets[8].op="Fe";presets[8].unit="Me";presets[8].vl="0.250";presets[8].v=0.250;
  presets[9].op="Fe";presets[9].unit="Me";presets[9].vl="0.300";presets[9].v=0.300;
  presets[10].op="Fe";presets[10].unit="Me";presets[10].vl="0.350";presets[10].v=0.350;
  presets[11].op="Fe";presets[11].unit="Me";presets[11].vl="0.400";presets[11].v=0.400;

}

void loop() {
  // put your main code here, to run repeatedly:

}

String test(String v, byte dir)//dir dictates which way the search goes
{

   if ((un=="Me")&&(op=="Th")) {return "test";}
   if ((op=="Th")&&(un=="Me")) {return "test";}

}

Which compiles fine, as you can see op and un are of type string. The original code is spread across 9 files to make it easier to debug. For me the weirdest thing is putting a comment on the same line after it then makes the line compile ok, makes no sense :crazy_face: I think my next step will be to create a new file and rewrite the code and delete the original file, another reason to split code across several files. This is not the first time I have come across weird things like this in the Arduino IDE, thankfully they are quite rare.

I think the setPresets function error is a bit of a red herring, it's the sort of error message you get when you forget a brace and the compiler doesn't see the next function, which as it happens, is the next function in that file. However, I have just created a new file, different name, and rewritten the the original function using EXACTLY the same lines and that compiles ok, I now find that the original function compiles ok with either of those lines! :face_with_symbols_over_mouth:, I've now deleted the new file and am using the original file again with no problems. So, half a day wasted and I'm still none the wiser.

You have my sympathy. When the good ppl here helped me run one of these infrequent but tots mysterious and annoying “errors” to ground, I think it turned out to be related to an extra blank line between an old style C comment and a new style ( /* */ and //).

Or something equally hard to believe could have kept us all busy for so long.

It is very rare, but that investigation did lead to an “adjustment” of some part of the compilation process, not the compiler but the preprocessor, which, as you observe, can serve up a fine banquets of red herring and wild geese.

If you see this one again, grab it in a bottle, no matter how large. I ended up (finally) “POST[ing] THE CODE”, which was horrible, large and a nasty sprawl; some genius whose name is forgotten but is still appreciated was able to bake it down to a MRE minimum reproducible error of a dozen or so lines of code.

a7

This error:

could certainly cause these two errors:

D:\Projects\Programing\Arduino\Boxford\BoxfordRA7855_encoder_update\Menu.ino: In function 'void mainMenu(int)':
Menu:29:44: 
error: 'getPreset' was not declared in this scope
case 13: num1=getPreset(num1,LOW);

D:\Projects\Programing\Arduino\Boxford\BoxfordRA7855_encoder_update\BoxfordRA7855_encoder_update.ino: In function 'void setup()':
BoxfordRA7855_encoder_update:120:14: 
error: 'setPresets' was not declared in this scope
setPresets(); //sets machining presets, code in preset unit

Now be a good person and mark this thread as solved to stop others from wasting time on it

yes, its the standard compiler response when a bracket is neglected and the compiler points out the first thing it can't find after that, if you see what I mean.

Trouble is the code now compiles, if it happens again, yes I'll repost, glad to know it's not just me that these glitches happen to, it's always on the last part of a project too, when there is no way of doing it another way! I'll mark this as solved although it isn't there seem to to be some junior techs that get a bit testy if they think it's solved and not flagged as such.

Of course it is. :expressionless:

a7

I'm glad I spotted this one early, and didn't waste half a day of my time on it.

1 Like

Probably just as well as you wouldn't have had anything useful to add anyway :kissing_heart:

With that attention to detail, and your attitude, you should go far.

Hopefully, you'll stay there

2 Likes

Whatever..

The extra braces could be confusing the compiler.
Try

if ((un=="Me")&&(op=="Th")) return "test";
if ((op=="Th")&&(un=="Me")) return "test";

If you must use braces even for a single statement, (which you don't), then the semicolon is in the wrong place:

if ((un=="Me")&&(op=="Th")) {return "test"};
if ((op=="Th")&&(un=="Me")) {return "test"};

Nope, the semicolons were in the right place in the original code (inside the braces). Omitting the semicolon inside the braces is a syntax error (a semicolon outside the braces is a valid null statement).

1 Like