Odd errors on one PC but not another

I'm using two machines. Both running the same version of OpenSuse Tumbleweed and Arduino 1.8.9.

I did most of the software development on machine A until it compiled cleanly and then switched to machine B for final compile and upload to Arduino.

However, the machine B is throwing up a load of compiler warnings on these lines of code:

unsigned long timerLists[][5] = { 
   {45*1000, 50*1000, 55*1000, 60*1000, 63*1000},			// 60 second timers
   {7*60*1000, 8*60*1000, 9*60*1000, 10*60*1000, 10*60*1000+3000},	// 10 minute timers
 };

There's an error like this for each integer defined in the array:

/home/me/Dev projects/Omni_timer/Omni_timer.ino:96:39: warning: integer overflow in expression [-Woverflow]
 unsigned long timerLists[][5] = {  {45*1000, 50*1000, 55*1000, 60*1000, 63*1000},   // 60 second timers

Repeated a bunch of times.
Then a load of these:

/home/me/Sync/Dev projects/Omni_timer/Omni_timer.ino:98:5: warning: narrowing conversion of '-20536' from 'int' to 'long unsigned int' inside { } [-Wnarrowing]

I'm mystified by the error in the first place given the explicit typing but why on one machine and not the other?

Any help gratefully received.

Firstly, compiler diagnostic messages depend on compiler settings, which may differ from machine to machine. Arduino IDE by default suppresses warnings. Apparently on your other machine this setting is changed.

Secondly, the message is justified. Your expressions do overflow. And no, there's no explicit typing there. Your expressions have int type and they don't fit into int, which is 16 bit wide on Arduino.

Interesting.

So what am I doing with unsigned long before the array definition?

How do I set the array elements as unsigned long?

Thanks.

lencsape:
Interesting.

So what am I doing with unsigned long before the array definition?

In C and C++ the type on the left-hand side of initialization (or assignment) has no effect on the interpretation of the right-hand side.

So, 45*1000 is evaluated independently of any context. It is evaluated as an int and overflows. The language does not care that you will later store the result in an unsigned long.

lencsape:
How do I set the array elements as unsigned long?

45ul * 1000 or (unsigned long) 45 * 1000

In a binary operator it is sufficient to force just one of its operands to unsigned long type to have the whole operator evaluate as unsigned long. I.e. formally there’s no need to say 45ul * 1000ul.

However, keep in mind that the same “language does not care about context” rule applies to subexpressions in expressions as well. For example, 30ul + 20000 * 3 is still broken, since subexpression 20000 * 3 is evaluated independently. It is evaluated as an int and overflows. A minimal fix would be 30 + 20000ul * 3. To avoid worrying about such details you might want to simply add ul suffix to all of your literals and forget about it.

Thank you for that illuminating reply. Coming from Python (recently, at least), I never expected integers to need an explicit type definition.

Much appreciated.

These are warnings, not errors. You can set the warnings level in the Arduino IDE at File > Preferences > Compiler Warnings. The default setting is “None”. I recommend always leaving it set to “All”, since warnings can be extremely helpful.

pert:
These are warnings, not errors. You can set the warnings level in the Arduino IDE at File > Preferences > Compiler Warnings. The default setting is “None”. I recommend always leaving it set to “All”, since warnings can be extremely helpful.

Well, two things:

Firstly, narrowing conversion inside an {} initializer is ill-formed in C++ - it’s a full-blown “error”, the code is invalid, the program is officially non-compilable in C++ language.

If GCC decided to report this it as a “warning” and continue compiling, it is a personal glitch/bug/quirk of GCC. GCC is well-known to report ill-formed code (i.e. “errors”) as “warnings” in default configuration. To make GCC report “errors” as “errors” one needs to set -pedantic-errors flag. And we have no direct access to it in Arduino IDE.

Secondly, cranking up the “Warning level” setting at least to “Default” is a must. Just remember that “These are warnings, not errors” logic does not apply to GCC. GCC, again, often reports full-blown “errors” as “warnings”.

It's not about what you think should be an error, or what would be an error if using a different compiler or different compiler settings. These are warnings, plain and simple.

I don't know that it's fair to claim this is a GCC glitch/quirk/bug. Arduino specifically instructed the compiler not to treat narrowing conversions as an error:

Yes, the reason they had to do that is because older compiler versions did treat it as a warning, which lead the authors of Arduino code who don't pay attention to warnings (probably don't even have them turned on) to write code that was broken by the compiler upgrade without this flag.

pert:
It's not about what you think should be an error, or what would be an error if using a different compiler or different compiler settings. These are warnings, plain and simple.

Well, it has nothing to do with what "I think". I'm simply remarking on what the C++ language says about it. All these decisions are made formally and set in stone. This code is, again, ill-formed in C++. This is the official term for what we colloquially call an "error".

pert:
I don't know that it's fair to claim this is a GCC glitch/quirk/bug. Arduino specifically instructed the compiler not to treat narrowing conversions as an error:
Treat narrowing conversion as warning, not error by PaulStoffregen · Pull Request #38 · arduino/ArduinoCore-avr · GitHub

Good information. So, this is not a GCC "glitch/quirk/bug", but rather an Arduino IDE's quirk of the proverbial "it is not a bug, it is a feature" variety.

While I understand the burdens associated with the old code, hardcoding this change, i.e. leaving the user without means to restore the standard behavior, is unacceptable. (Yes, I know that one can manually alter their platform.txt, but it usually takes more than that). This is where "what I think" comes into the picture.

pert:
Yes, the reason they had to do that is because older compiler versions did treat it as a warning, which lead the authors of Arduino code who don't pay attention to warnings (probably don't even have them turned on) to write code that was broken by the compiler upgrade without this flag.

Well, again, C++ has no concept of "errors" or "warnings". There are are only diagnostic messages. Telling which diagnostic messages are mandated by the language ("errors", the code is ill-formed), and which ones are just superficial compiler's concerns ("just a warning") is the responsibility of the user.

So, even if GCC in Arduino IDE reports it as a "warning" (for whatever reason), it is not "just a warning" and cannot be dismissed as such. That is the point I was making in my previous message.