pic18, xc8, v2.05, arithmetic overflow in constant expression

spinnaker

Joined Oct 29, 2009
7,830
in BR_9600, I need to mask the number to be a byte (within 0xFF), the others are just copy and paste.
WHY ARE YOU DOING IT IN CODE???

You don't need to do that in code. Figure it out your self and use that value


SPBRG = 0xA0, is exactlly the same thing and you won't get the warning.
 
@spinnaker No worries. @Raymond Genovese beat us both to it, in this post!
Thanks, but I think @spinnaker saw what he was doing in post #3. I was more interested in figuring out why he was getting the warning (and I'm still not clear about that).

In any case, @bug13 do you understand that you can re-write that line and not get the warning at all?

Also, if that value is something that you might want to play with later, you could put it in a global (or a #define) along with some healthy comments to remind you. Something like

uint8_t SPBRGValue= 0xa0; // blah blah blah reasoning
...and then later...
SPBRG = SPBRGValue;
 
Last edited:

spinnaker

Joined Oct 29, 2009
7,830
Thanks, but I think @spinnaker saw what he was doing in post #3. I was more interested in figuring out why he was getting the warning (and I'm still not clear about that).

In any case, @bug13 do you understand that you can re-write that line and not get the warning at all?

Also, if that value is something that you might want to play with later, you could put it in a global (or a #define) along with some healthy comments to remind you. Something like

uint8_t SPBRGValue= 0xa0; // blah blah blah reasoning
...and then later...
SPBRG = SPBRGValue;

Warning was generated because the developer of the compiler never realized the programmer would do such a thing. ;)
 
Warning was generated because the developer of the compiler never realized the programmer would do such a thing. ;)
I hear you and you are right (including the wink), but sometimes xc compilers can frustrate the ____ out of me. It is a little OT, but a few months ago, I was working with xc32...trying to get something to work. I threw a delay loop into my code...

C:
void wait(){
  unsigned int i;
  for (i = 0; i < 1400000; i += 1){
  }
}
Now, I know that you don't do a delay like that, but as a quick debugging aid, I have done that and many times......tell me you made it here by keeping the LED on or flashing or whatever...I don't care about blocking or precise time, I just want to see a difference...that sort of thing.

xc32 will compile that fine - no errors and no warnings (at least not at the default level)...and it will also completely remove that code, arrogantly assuming that you should not be writing empty loops.

It was driving me crazy...and then I figured it out and used...

C:
void wait(){
  unsigned int i;
  for (i = 0; i < 1400000; i += 1){
  _nop();
  }
}
..and all was well in the world.

I hate cursing inanimate objects.

edited to add..I would like to see some kind of directive added...

__shutupanddowhatItellyou ON
__shutupanddowhatItellyou OFF

edited again to add...come to think of it, I wouldn't mind seeing such a switch on people, but that is another matter :)
 
Last edited:

djsfantasi

Joined Apr 11, 2010
9,163
I hear you and you are right (including the wink), but sometimes xc compilers can frustrate the ____ out of me. It is a little OT, but a few months ago, I was working with xc32...trying to get something to work. I threw a delay loop into my code...

C:
void wait(){
  unsigned int i;
  for (i = 0; i < 1400000; i += 1){
  }
}
Now, I know that you don't do a delay like that, but as a quick debugging aid, I have done that and many times......tell me you made it here by keeping the LED on or flashing or whatever...I don't care about blocking or precise time, I just want to see a difference...that sort of thing.

xc32 will compile that fine - no errors and no warnings (at least not at the default level)...and it will also completely remove that code, arrogantly assuming that you should not be writing empty loops.

It was driving me crazy...and then I figured it out and used...

C:
void wait(){
  unsigned int i;
  for (i = 0; i < 1400000; i += 1){
  _nop();
  }
}
..and all was well in the world.

I hate cursing inanimate objects.

edited to add..I would like to see some kind of directive added...

__shutupanddowhatItellyou ON
__shutupanddowhatItellyou OFF

edited again to add...come to think of it, I wouldn't mind seeing such a switch on people, but that is another matter :)
Yeah, Yeah,... Yeah!

Compilers that do code optimization by default can wreak all kinds of havoc. Fortunately, you can turn that “feature” off in the Arduino IDE. Sometimes, I’ll test the code twice. With and without optimization. Caught and killed a few gotcha’s with that process.
 

WBahn

Joined Mar 31, 2012
30,052
I hear you and you are right (including the wink), but sometimes xc compilers can frustrate the ____ out of me. It is a little OT, but a few months ago, I was working with xc32...trying to get something to work. I threw a delay loop into my code...

C:
void wait(){
  unsigned int i;
  for (i = 0; i < 1400000; i += 1){
  }
}
Now, I know that you don't do a delay like that, but as a quick debugging aid, I have done that and many times......tell me you made it here by keeping the LED on or flashing or whatever...I don't care about blocking or precise time, I just want to see a difference...that sort of thing.

xc32 will compile that fine - no errors and no warnings (at least not at the default level)...and it will also completely remove that code, arrogantly assuming that you should not be writing empty loops.

It was driving me crazy...and then I figured it out and used...

C:
void wait(){
  unsigned int i;
  for (i = 0; i < 1400000; i += 1){
  _nop();
  }
}
..and all was well in the world.

I hate cursing inanimate objects.

edited to add..I would like to see some kind of directive added...

__shutupanddowhatItellyou ON
__shutupanddowhatItellyou OFF

edited again to add...come to think of it, I wouldn't mind seeing such a switch on people, but that is another matter :)
You were lucky -- putting ANYTHING into the loop kept it from getting culled. I've had times when I've had to put in code that was actually used for something the couldn't be culled.

The optimization done by modern compilers borders on outright sorcery. I'm more than willing to admit that it is pretty amazing what it can do -- but there are simply times that I just want the damn compiler to do what I told it to do and not what it thinks I should have wanted to do.
 
Last edited:

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Ok, 416 decimal is 110100000 binary

416 & 0x00FF 10100000 binary
Or 160 decimal.

SBPRG = 160

This is the same conclusion that @Raymond Genovese came to. What is SPBRG declared as? You may need to cast 160 as the same type.
I think I still don't understand it correctly, as I believe I did cast it to same type:
Here is my original code:
SPBRG = (uint8_t) (416UL & 0x00FF);
Then I realize that UL is different from U, so I changed it to:
SPBRG = (uint8_t) (416U & 0x00FF); // still have warning

But anyway I will just put 160 in there to get rid of the warning for now.
 

WBahn

Joined Mar 31, 2012
30,052
I think I still don't understand it correctly, as I believe I did cast it to same type:
Here is my original code:
SPBRG = (uint8_t) (416UL & 0x00FF);
Then I realize that UL is different from U, so I changed it to:
SPBRG = (uint8_t) (416U & 0x00FF); // still have warning

But anyway I will just put 160 in there to get rid of the warning for now.
Do you get the same warning if, instead of 416, you make it 216?
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
WHY ARE YOU DOING IT IN CODE???

You don't need to do that in code. Figure it out your self and use that value


SPBRG = 0xA0, is exactlly the same thing and you won't get the warning.
I do find it easier to read, I guess that's a personal thing. It's the same reason I like to do this:
Code:
#define ONE_MS          (1UL)    // I usually do one tick per ms
#define ONE_SECOND      (ONE_MS * 1000UL)
#define ONE_MINUTE      (ONE_SECOND * 60UL)
Instead of doing this:
Code:
#define ONE_MS          (1UL)    // I usually do one tick per ms
#define ONE_SECOND      (1000UL)
#define ONE_MINUTE      (60000UL)
The above is just an simple example, but in a more complicated code( eg in multiple files), I find it easier to read and less bugs in general. As I can only change one variable and everything else will be updated to the correct value. Instead of every time if I need to change something, I need to manually go through all and update all others relative variables.

But I do understand in this case it's no good, so I will just change it and stick 160 in my code.
 

djsfantasi

Joined Apr 11, 2010
9,163
Do you get the same warning if, instead of 416, you make it 216?
Great suggestion, @WBahn ! I see where you are going.

I must admit that I’m confounded by the effort in eliminating these warnings. As my grandfather might say, they’re constants for cripes sake! There’s no reason not to perform the calculation manually and define the variable in the code as a const with a value of 160 (decimal). If you want to remember how that value was determined, the correct place is not in the code but with a comment.
 

djsfantasi

Joined Apr 11, 2010
9,163
However it is obvious to me that this is the incorrect data type for this calculation. By removing the U, the compiler will match up the datatypes for you. I believe. Hence the result may be no warning. Try it. Since you’re so opposed to use the calculated value.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
However it is obvious to me that this is the incorrect data type for this calculation. By removing the U, the compiler will match up the datatypes for you. I believe. Hence the result may be no warning. Try it. Since you’re so opposed to use the calculated value.
I still have the same warning, tried both:
Code:
SPBRG = (uint8_t) (416 & 0x00FF);
SPBRG = (uint8_t) (416 & 0xFF);
 
Top