Searching \ for '[EE] C integer promotions' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/language/index.htm?key=c
Search entire site for: 'C integer promotions'.

Exact match. Not showing close matches.
PICList Thread
'[EE] C integer promotions'
2008\07\09@180200 by Tomás Ó hÉilidhe

picon face


Tomás Ó hÉilidhe wrote:
> For instance, on
> a trully 16-Bit processor, you can't do operations on a 16-Bit integer,
> only 32-Bit. Unfortunately though, integer promotion isn't very fitting
> for systems where int is less than 16-Bit, but the PIC C compiler
> handles it flawlessly!
>  


That should have read:

   "on a trully 32-Bit processor, you can't do..."

2008\07\09@181919 by Rolf

face picon face
Tomás Ó hÉilidhe wrote:
> Herbert Graf wrote:
>  
>> That said, I am interested in the "integer promotion". What ARE the
>> rules for promotion? I have been hit a couple times with promotion
>> happening when I didn't think it would, and other times not happening
>> when I thought it should have.
>>
>> What are common "gotchas" with regards to type promotion?
>>
>> Since I'm not that familiar with the rules, I generally explicitly cast
>> so that I don't have to worry about them, but now I'm curious! :)
>>    
>
>
> OK here goes I'll try give an exhaustive yet finite explanation of
> integer promotion. You should probably put the kettle on.
>  

[snip]....

nope, no tea for me.

Read section 2.7 of the C18 user's guide, and discover that all your
theories about what C compilers can and should do are different to your
understanding....

Here's the URL. Get yourself a cup of coffee/tea, and decide who's got
an absolut eunderstanding of all C compilers.... ;-)

http://ww1.microchip.com/downloads/en/DeviceDoc/C18_User_Guide_51288j.pdf

Rolf

2008\07\10@000200 by Christopher Head

picon face
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Rolf wrote:
[snip]
| [snip]....
|
| nope, no tea for me.
|
| Read section 2.7 of the C18 user's guide, and discover that all your
| theories about what C compilers can and should do are different to your
| understanding....
|
| Here's the URL. Get yourself a cup of coffee/tea, and decide who's got
| an absolut eunderstanding of all C compilers.... ;-)
|
| ww1.microchip.com/downloads/en/DeviceDoc/C18_User_Guide_51288j.pdf
|
| Rolf
|

In case anybody was wondering, "Tomas's theories" as you describe them
also happen to be ISO's theories, also known as standards... not that
this makes Microchip obey them. In this case it's a good thing they
don't, as promotion to int would be inefficient in a PIC whose native
data word size is 8 bits. MCC18 is a thing that looks an awful lot like
a C compiler, but actually isn't quite. However, this is not necessarily
a bad thing.

Chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: GnuPT 2.7.2
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkh1iacACgkQiD2svb/jCb6HPQCffVgLhPAcSOLsskJS+FAwcZsS
AUsAnR2UE/B0ZzswC6wJoyo131XgfdXY
=yovc
-----END PGP SIGNATURE-----

2008\07\10@030453 by Tamas Rudnai

face picon face
> In case anybody was wondering, "Tomas's theories" as you describe them
> also happen to be ISO's theories, also known as standards... not that
> this makes Microchip obey them. In this case it's a good thing they
> don't, as promotion to int would be inefficient in a PIC whose native
> data word size is 8 bits. MCC18 is a thing that looks an awful lot like
> a C compiler, but actually isn't quite. However, this is not necessarily
> a bad thing.

There are couple of things to consider about this subject:

1. Tomas claims that the integer promotion _have to be done_. I think there
is a problem about the wording here. For me 'have to' means if you do not do
that the bitwise operation will fail. I can't see any case when it would be,
so promotion do _not have to be_ promoted.

2. In many platforms integer promotion is highly inefficient - like 8 bit
MCUs and Intel x86. In 8 bit platforms because as you said the code would be
too large, in x86 because in this way you cannot use 8 bit registers to
store more temporary data or register variables. That is sad that too many
compilers follow a standard even if the standard is inadequate.

3. Tomas also claims that compilers change my unsigned char to signed int
and that's why have to cast manually the unsigned char to unsigned int first
so that the compiler no more promote the variable to signed int. That makes
sense with little side notes: First of all in bitwise operations it should
not be affected - nor with the back conversion and I really think that
claiming some "super computer" that uses different representations for
signed integers are not a valid situations nowadays. Secondly this behavior
from the compiler is bad therefore that is a bad compiler and should be
avoided when it is possible. The idea behind this integer promotion is to be
able to handle the situation not to make it worse. As Tomas mentioned about
"truly 32 bit systems", I think he meant when the CPU does not have smaller
register size than 32 bit and/or when the memory address circuit is unable
to address a byte or a word. So on these systems of course you have no
choice you have to convert the smaller to the supported size, but should not
change the sign type. And finally on such system in terms of speed of code
it is more efficient to keep everything on the supported size (aka int)
therefore no promotion is needed. If you think it over most original C
standard libraries used int as a parameter or return type, like getch.

Anyway, I agree with Alan here, loads of rubbish about non-existent problems
and their solutions.

Tamas



On Thu, Jul 10, 2008 at 5:01 AM, Christopher Head <spam_OUTcheadTakeThisOuTspamtelus.net> wrote:

{Quote hidden}

> -

2008\07\10@070424 by Tomás Ó hÉilidhe

picon face

Tamas Rudnai wrote:

>  1. Tomas claims that the integer promotion _have to be done_. I think
there
>  is a problem about the wording here. For me 'have to' means if you do
not do
>  that the bitwise operation will fail. I can't see any case when it
would be,
>  so promotion do _not have to be_ promoted.


You can have a compiler that *doesn't* do it, and it might even be a
great compiler. The only thing I'm saying is that, in standardised C,
the integer promotion must occur.

And by "must occur", I mean the program must behave as though the
promotion occurred. For instance, if you have:

   char unsigned a;

and then do:

   sizeof(a)

then that must be 1. However, if you do:

   sizeof(~a)

then it must be the same size as an int.

However, what must be taken into account is the "as if" principle. A
compiler can do whatever it likes under the bonnet so long as it behaves
"as if" it's following the rules. More on this below.


>  2. In many platforms integer promotion is highly inefficient - like 8 bit
>  MCUs and Intel x86. In 8 bit platforms because as you said the code
would be
>  too large, in x86 because in this way you cannot use 8 bit registers to
>  store more temporary data or register variables. That is sad that too many
>  compilers follow a standard even if the standard is inadequate.


That was my first thought as well; I thought it'd be very inefficient.
But then I tried out PIC C. Here's some code I ran through it:

int main(void)
{
   char unsigned volatile a, b;

   a = 0x32;

   b = a * 2 + 7;
}

(I use "volatile" to inform the compiler that it can't optimise memory
accesses to this variable. This makes sure I get the detailed assembler
I want.)

And here's the assembler I got:

  ('a' is located at 0x21, 'b' is located at 0x20)

  7F7    3032     MOVLW 0x32          /* Set accumulator to 0x32 */
  7F8    1283     BCF 0x3, 0x5           /*  Set appropriate memory bank */
  7F9    00A1     MOVWF 0x21        /*  Move accumulator to 'a' */
  7FA    0821     MOVF 0x21, W      /*  Move 'a' to the accumulator */
  7FB    0721     ADDWF 0x21, W   /*  Double the accumulator */
  7FC    3E07     ADDLW 0x7           /* Add 7 to the accumulator */
  7FD    00A0     MOVWF 0x20       /* Move accumulator to 'b' */

As you can see, there's no need to use more than one byte for a number
in the above, even thought the integer promotion rules are still being
followed. Also we can prove that integer promotion does occur by using
sizeof; here's the C code along with its disassembly:

7:                     a = sizeof(a);
  7F9    3001     MOVLW 0x1
  7FA   00A0     MOVWF 0x20
8:                
9:                     a = sizeof(~a);
  7FC    3002     MOVLW 0x2
  7FD    00A0     MOVWF 0x20

Now let's see what happens though if we use a number bigger than 255:

Here's the C code:

int main(void)
{
   char unsigned volatile a, b;

   a = 0x32;

   b = a * 300 + 7;
}

And here's the lengthly disassembly:

---  x:\bmul.as  ----------------------
  7F4    00FE     MOVWF 0x7e
  7F6    187F     BTFSC 0x7f, 0
  7F7    077E     ADDWF 0x7e, W
  7F8    1003     BCF 0x3, 0
  7F9    0DFE     RLF 0x7e, F
  7FA    1003     BCF 0x3, 0
  7FB    0CFF     RRF 0x7f, F
  7FC    08FF     MOVF 0x7f, F
  7FD    1903     BTFSC 0x3, 0x2
  7FF    2FF6     GOTO 0x7f6
  7FE    0008     RETURN
---  x:\main.c  -----------------------
1:                 #include <pic.h>
2:                
3:                 int main(void)
4:                 {
5:                     char unsigned volatile a, b;
6:                
7:                     a = 0x32;
  7E9    3032     MOVLW 0x32
  7EA    1283     BCF 0x3, 0x5
  7EB    00A1     MOVWF 0x21
8:                
9:                     b = a * 300 + 7;
  7EC    302C     MOVLW 0x2c
  7ED    00FF     MOVWF 0x7f
  7EE    0821     MOVF 0x21, W
  7EF    27F4     CALL 0x7f4
  7F0    3E07     ADDLW 0x7
  7F1    00A0     MOVWF 0x20
10:                }
  7F2    0183     CLRF 0x3


So as you can see, PIC *will* bring in bigger size numbers if it has to,
otherwise it will stay with one byte. It handles integer promotion
flawlessly.


>  3. Tomas also claims that compilers change my unsigned char to signed int
>  and that's why have to cast manually the unsigned char to unsigned int
first
>  so that the compiler no more promote the variable to signed int. That
makes
>  sense with little side notes: First of all in bitwise operations it should
>  not be affected - nor with the back conversion and I really think that
>  claiming some "super computer" that uses different representations for
>  signed integers are not a valid situations nowadays.


For 2's complement you won't have a problem, but you *will* have a
problem for 1's complement and signed-magnitude. The way around this is
to have:

   a = ~(unsigned)b;

instead of:

   a = ~b;


>  Secondly this behavior
>  from the compiler is bad therefore that is a bad compiler and should be
>  avoided when it is possible.


This behaviour is Standard as per the ISO ANSI Standard.


>  The idea behind this integer promotion is to be
>  able to handle the situation not to make it worse. As Tomas mentioned
about
>  "truly 32 bit systems", I think he meant when the CPU does not have
smaller
>  register size than 32 bit and/or when the memory address circuit is unable
>  to address a byte or a word.


That's what I meant, yes.


>  Anyway, I agree with Alan here, loads of rubbish about non-existent
problems
>  and their solutions.


I prefer to sleep sound knowing my code will work anytime, anywhere. I
don't want to get a phonecall at 2 in the morning from planet Zargon
telling me my program doesn't work on their 2048-Bit Sign-magnitude
inter-galactic hypercomputer.


2008\07\10@075245 by Tamas Rudnai

face picon face
Tomas,

I like the way now we started to argue, no personal insulation which is
great and the best way to discuss abut engineering or developing, thanks for
that!

I can't see that integer promotion, so please tell me where did I miss it.
Actually I see byte promotion I would say.

Here is the detailed analysis of the listing file you posted:

> ---  x:\bmul.as  ----------------------
>   7F4    00FE     MOVWF 0x7e          ; puts W->'a'->0x32 into a temp file
>   7F6    187F     BTFSC 0x7f, 0       ; beginning of the multiplication
loop
>   7F7    077E     ADDWF 0x7e, W       ; adds the shifted number to W
>   7F8    1003     BCF 0x3, 0          ; forget C so do not care about
overflow
>   7F9    0DFE     RLF 0x7e, F         ; shift temp value 'up' (that's why
C was cleared)
>   7FA    1003     BCF 0x3, 0          ; forget C again - need for next
shift again
>   7FB    0CFF     RRF 0x7f, F         ; shift multiplier 'down'
>   7FC    08FF     MOVF 0x7f, F        ; this is only for checking if
multiplier is zero
>   7FD    1903     BTFSC 0x3, 0x2      ; Z flag...
>   7FF    2FF6     GOTO 0x7f6          ; not zero, go back to the beginning
of loop
{Quote hidden}

the
                                       ; least significant 8 bits! (BYTE
PROMOTION?)
>   7ED    00FF     MOVWF 0x7f          ; store it in temp variable
>   7EE    0821     MOVF 0x21, W        ; get 'a' in W
>   7EF    27F4     CALL 0x7f4          ; here we go, let's multiply it
>   7F0    3E07     ADDLW 0x7           ; add 7 to the results
>   7F1    00A0     MOVWF 0x20          ; store number in 'b'
> 10:                }
>   7F2    0183     CLRF 0x3
>

Thanks
Tamas




On Thu, Jul 10, 2008 at 12:03 PM, Tomás Ó hÉilidhe <.....toeKILLspamspam@spam@lavabit.com> wrote:

{Quote hidden}

>

2008\07\10@080810 by Walter Banks

picon face


Tomás Ó hÉilidhe wrote:

{Quote hidden}

The compiler gives the correct results (as if rule) but what
was actually compiled is


b = a * 44 + 7;

w..

2008\07\10@083522 by Alan B. Pearce

face picon face
>The compiler gives the correct results (as if rule) but what
>was actually compiled is
>
>b = a * 44 + 7;

Which ends up being correct - because the integer is cast back to a char, so
the compiler is cunning enough to not bother handling the high byte at all
as it is never used.

However I wonder what the assembly code would be if the C source was

    b = (a * 300 + 7)>>8;

More... (looser matching)
- Last day of these posts
- In 2008 , 2009 only
- Today
- New search...