Apropos casting...

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just as an example, and only because it slowed me down for a moment or two...

 

	while ((uint16_t)regs.pc != next_instruction_address)
	{
		interpret_and_disassemble();
	}

next_instruction_address is uint16_t; regs.pc is int16_t.

 

Without the cast, in some circumstances (e.g. regs.pc = 0xff00) the while loop takes forever... why?

 

Because regs.pc can have a negative value and next_instruction_address can't. Hence when regs.pc is negative, they can never be equal and so the loop never terminates. Yet the bit pattern is identical... it's all a question of how it's interpreted.

 

And why is regs.pc signed I hear you ask? Short answer: can't remember. I think it was so some of the indexed addressing modes worked properly.

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What platform is this ?

It would make sense if you have 32 bit int.

Doesn't make sense for 16 bit int (it would be the same without the cast in that case).

 

Integer promotions are applied for the != operation.

With 32 bit int, both uint16_t and int16_t promote to int (which is signed) and int is the type usd for the != operation.

So assuming 32 bit int,

uint16_t value of 65280 (0xff00) promotes to int, value unchanged so still 65280 (0x0000ff00)

int16_t value of -256 (0xff00) promotes to int, value unchanged so still -256 (0xffffff00)

and -256 is not equal to 65280

 

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

barnacle wrote:
Without the cast, in some circumstances (e.g. regs.pc = 0xff00) the while loop takes forever... why?
The first pass through a linter was acceptable; enabled MISRA for the next pass that identified Rule 10.4

In a C coding standard :

INT02-C. Understand integer conversion rules - SEI CERT C Coding Standard - Confluence

via MISRA C:2012 - SEI CERT C Coding Standard - Confluence

 


PC-lint Plus Online Demo - Gimpel Software - The Leader in Static Analysis for C and C++ with PC-lint Plus

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For avr-gcc (I suppose any gcc also) you must enable this specific warning -Wsign-compare to catch it.

 

https://godbolt.org/z/a31v5b

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes - GCC on linux (I thought I'd said that in the original post - I certainly thought I did :) but as indicated, no warning - which I would argue is probably a mistake.

 

I just thought it was a useful reminder, given the recent thread on casting, that while the bits don't change, the interpretation of those bits does - in this case, with a hidden promotion to wider (probably 64-bit) int.

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wayell, if regs.pc monotonically changes, there are six possibilities, none of which involves looping forever1:

 

1) regs.pc is negative and descending

   1a) eventually, it'll wrap its counter and turn positive again, thus will, sooner or later, match

2) regs.pc is negative and ascending

   2a) eventually, regs.pc will become positive and match

3) regs.pc is positive. greater than and descending

   3a) Therefore it'll match soon

4) regs.pc is positive, less than, and descending

   4a) Therefore it'll wrap around, to negative, through all the negative numbers, and back down from top again, eventually matching

5) regs.pc is positive, greater than, and ascending

   5a) Therefore it'll wrap around, to negative, through all the negative numbers, and back up from zero again, eventually matching

6) regs.pc is positive, less than, and ascending

   6a) Then it'll match soon.

 

S.

 

1. Now, some of them might take a rather long time, especially if promoted to 64 bits, but not forever in a literal sense...

 

Edited to fix bad paste job.

Last Edited: Sun. Nov 1, 2020 - 07:35 PM