Compiler error Error?

void calc_time()
 {
  uint16_t total_time = 0;
  total_time = 18*60*60;
 }
xxx.ino:263:21: warning: integer overflow in expression [-Woverflow]
   total_time = 18*60*60;

I thought the maximum value of uint16_t was 65535? 186060 = 64800. What gives?

The RHS defaults to signed int evaluation, which DOES overflow. The compiler does not lie.

Either cast a constant on the RHS to unsigned int, or append "UL", to force unsigned long, which you will need for seconds per day (86400 of them) in any case.

jremington:
The RHS defaults to signed int evaluation, which DOES overflow. The compiler does not lie.

Will the compiler 'pre-compile' the result or execute the math when the time comes?

jremington:
Either cast a constant on the RHS to unsigned int, or append "UL", to force unsigned long, which you will need for seconds per day (86400 of them) in any case.

I believe that is what is called an assumption. The OP is why the compiler throws a warning on a value that is not beyond the limits of the data type. The exact code and error are posted.

The value is beyond the limits of the data type of the expression, which is “int”.

That is exactly what the warning says.

Will the compiler ‘pre-compile’ the result

Yes, it will.

TheMemberFormerlyKnownAsAWOL:
The value is beyond the limits of the data type of the expression, which is "int".

That is exactly what the warning says.

While that is a true statement and the value is beyond that of an int. The variable is not of type int, but u(nsigned)int.

adwsystems:
The variable is not of type int, but u(nsigned)int.

That does not matter; the calculation is done with int and later assigned to an uint.

sterretje:
That does not matter; the calculation is done with int and later assigned to an uint.

OK.
Follow up question:

void calc_time()
 {
  uint16_t total_time = 0;
  total_time = 64800+1;
 }

But the compiler realizes it should use unsigned int for 64800+1, 64800*1, as it produces no error?

P.S. I'm playing right at the edge of not enough memory and trying to squeeze out (or in) every bit and byte.

The value 64800 is recognised as a uint16_t.
It won’t overflow if you add one to it.
No problem.

What I don’t understand is why you initialise the variable to zero first. I can only hope that for one on such a tight memory budget, the compiler optimises that away.

TheMemberFormerlyKnownAsAWOL:
The value 64800 is recognised as a uint16_t.
It won't overflow if you add one to it.
No problem.

What I don't understand is why you initialise the variable to zero first.

To provide the MCVE I would be otherwise asked for. There is more to the code outside the question.

So, it isn’t actually a MCVE, is it?

TheMemberFormerlyKnownAsAWOL:
So, it isn't actually a MCVE, is it?

I provide one and get bashed anyway. Sometimes I wonder why I try. I should have posted the 200 lines of code and let some complain about that.

The OP is why the compiler throws a warning on a value that is not beyond the limits of the data type.

The correct answer was given in the first line of reply #1. You can attempt to continue with your pointlessly adversarial responses, but it won't get you any further.

TheMemberFormerlyKnownAsAWOL:
The value 64800 is recognised as a uint16_t.
It won't overflow if you add one to it.

The type will be long, not uint16_t (at least on a platform where int is 16 bits).

You can find the rules for integer literals here: Integer literal - cppreference.com
Unless you explicitly add a u suffix, decimal integer literals are never unsigned.
Hexadecimal, octal and binary literals may be unsigned, depending on their value, e.g. the type of 0x8000 is unsigned int, but 32768 (the same number in decimal) has type long int.

Pieter

Thanks for the correction - what I meant to write was “The value 64800 is recognised as capable of fitting in a uint16_t without overflow”, but Christmas Eve being Christmas Eve, and beer being beer…

adwsystems:

xxx.ino:263:21: warning: integer overflow in expression [-Woverflow]

total_time = 186060;



I thought the maximum value of uint16_t was 65535? 18*60*60 = 64800. What gives?

The expression 186060 is not unsigned. I mean - it gets assigned to an unsigned variable, but that's right at the end of the process. The multiplication is a signed multiplication.

Try 18U60U60U.