EmbeddedRelated.com
Forums

Warning in IAR when performing bitwise not on unsigned char (corrected)

Started by distantship101 April 3, 2012
[sorry there was some errors in the previous message]

Hi,

When compiling :

typedef unsigned short x_t;
extern x_t xOpen(void);
x_t r = ~xOpen( );

I get no warning, but if I change the type of x_t to unsigned char :

typedef unsigned char x_t;
extern x_t xOpen(void);
x_t r = ~xOpen( );

the assignment generates the following warning:

Remark[Pa091]: operator operates on value promoted to int (with possibly unexpected result)

Is this behavior correct ? And if yes, how do I write the assignment to avoid the warning ?

Thanks

Beginning Microcontrollers with the MSP430

> When compiling :
>
> typedef unsigned short x_t;
> extern x_t xOpen(void);
> x_t r = ~xOpen( );
>
> I get no warning

Correct.

> but if I change the type of x_t to unsigned char :
>
> typedef unsigned char x_t;
> extern x_t xOpen(void);
> x_t r = ~xOpen( );
>
> the assignment generates the following warning:
>
> Remark[Pa091]: operator operates on value promoted to int (with possibly
> unexpected result)
>
> Is this behavior correct ?

The warning is correct, yes. unsigned char gets promoted to plain signed
int before ~ inverts it.

> And if yes, how do I write the assignment to avoid the warning ?

x_t r = ~(unsigned)xOpen();

Quite what you'd want to use unsigned char as a return type on a 16-bit
machine, I have no idea. If it is in the (mistaken) belief that smaller
types generate "better code", this is not true on the MSP430.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore running Defender... http://www.vimeo.com/25709426

--- In m..., "Paul Curtis" wrote:
>
> Quite what you'd want to use unsigned char as a return type on a 16-bit
> machine, I have no idea. If it is in the (mistaken) belief that smaller
> types generate "better code", this is not true on the MSP430.

Thanks for your reply. The example I gave was fabricated and I used a return value to make sure no assumption could be made about the value. I encountered the problem while compiling third-party library code.

Paul,

I always read your posts as you have taught me some important and useful things about compilers. Would you care to expand on this remark below? I always use unsigned chars as return types on the MPS430, just as you say, assuming it uses less space than words and will run faster. I use them as my default variable for the same reason. Please tell us more.

Lloyd

--- In m..., "Paul Curtis" wrote:

> Quite what you'd want to use unsigned char as a return type on a 16-bit
> machine, I have no idea. If it is in the (mistaken) belief that smaller
> types generate "better code", this is not true on the MSP430.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> SolderCore running Defender... http://www.vimeo.com/25709426
>

Since the MSP430 is a 16-bit machine, I think there are no differences in number of cycles or code memory used in byte versus word accesses.

Emmett Redd Ph.D. mailto:E...@missouristate.edu
Professor (417)836-5221
Department of Physics, Astronomy, and Materials Science
Missouri State University Fax (417)836-6226
901 SOUTH NATIONAL Lab (417)836-3770
SPRINGFIELD, MO 65897 USA Dept (417)836-5131

In statesmanship get the formalities right, never mind about the moralities. -- Mark Twain.
________________________________________
From: m... [m...] On Behalf Of lslonim2 [l...@our3cats.com]
Sent: Thursday, April 12, 2012 4:29 PM
To: m...
Subject: [msp430] Re: Warning in IAR when performing bitwise not on unsigned char (corrected)

Paul,

I always read your posts as you have taught me some important and useful things about compilers. Would you care to expand on this remark below? I always use unsigned chars as return types on the MPS430, just as you say, assuming it uses less space than words and will run faster. I use them as my default variable for the same reason. Please tell us more.

Lloyd

--- In m..., "Paul Curtis" wrote:

> Quite what you'd want to use unsigned char as a return type on a 16-bit
> machine, I have no idea. If it is in the (mistaken) belief that smaller
> types generate "better code", this is not true on the MSP430.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> SolderCore running Defender... http://www.vimeo.com/25709426
>



lslonim2 wrote:
> Paul,
>
> I always read your posts as you have taught me some important and useful things about compilers. Would you care to expand on this remark below? I always use unsigned chars as return types on the MPS430, just as you say, assuming it uses less space than words and will run faster. I use them as my default variable for the same reason. Please tell us more.
>
> Lloyd

Hi Lloyd,
Most everything is done through the registers. If you load a char, it
will take the whole register. Values from calls will be in a register,
so 16 bits even if uint8_t; you don't use memory here. Now, memory is
byte size. So thinking bytes in memory will save space but it won't save
machine cycles. OPCODE and OPCODE.B will always use the same number of
cycles.

Best, Dan.

--
Newspapers are unable, seemingly to discriminate between a bicycle accident and the collapse of civilization.
George Bernard Shaw

You normally want to use the natural size for the hardware. I used to write code
for Cray which has
64 bits as its natural machine size. It was faster to use 64bit integer than a 1
bit boolean.
(That is an extreme example, but illustrative)

If you add a constraint like it must be a 8bit unsigned, then 16bit needs to be
masked to be 8bits.
Maybe one or two more machine instructions, not much, but not needed.
Also you may have code alignment issues where extra blank spaces get inserted to
force
alignment on 16bit addresses. That could make the code messy.

Returns are done on the stack and you can only push and pop a 16bit word on the
stack.
So there is no time savings by specifying 8 bits.

----- Original Message ----
From: lslonim2
To: m...
Sent: Thu, April 12, 2012 2:29:35 PM
Subject: [msp430] Re: Warning in IAR when performing bitwise not on unsigned
char (corrected)

Paul,

I always read your posts as you have taught me some important and useful things
about compilers. Would you care to expand on this remark below? I always use
unsigned chars as return types on the MPS430, just as you say, assuming it uses
less space than words and will run faster. I use them as my default variable for
the same reason. Please tell us more.

Lloyd

--- In m..., "Paul Curtis" wrote:

> Quite what you'd want to use unsigned char as a return type on a 16-bit
> machine, I have no idea. If it is in the (mistaken) belief that smaller
> types generate "better code", this is not true on the MSP430.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> SolderCore running Defender... http://www.vimeo.com/25709426
>

Return values use registers, not the stack - otherwise the compiler would have to generate code to swap the return address with the return value ... now calling parameters are pushed onto the stack - although Crossworks uses a register for the first calling parameter and the stack if there are additional parameters.
----- Original Message -----
From: Eric
To: m...
Sent: Thursday, April 12, 2012 15:09
Subject: Re: [msp430] Re: Warning in IAR when performing bitwise not on unsigned char (corrected)

You normally want to use the natural size for the hardware. I used to write code
for Cray which has
64 bits as its natural machine size. It was faster to use 64bit integer than a 1
bit boolean.
(That is an extreme example, but illustrative)

If you add a constraint like it must be a 8bit unsigned, then 16bit needs to be
masked to be 8bits.
Maybe one or two more machine instructions, not much, but not needed.
Also you may have code alignment issues where extra blank spaces get inserted to
force
alignment on 16bit addresses. That could make the code messy.

Returns are done on the stack and you can only push and pop a 16bit word on the
stack.
So there is no time savings by specifying 8 bits.

----- Original Message ----
From: lslonim2
To: m...
Sent: Thu, April 12, 2012 2:29:35 PM
Subject: [msp430] Re: Warning in IAR when performing bitwise not on unsigned
char (corrected)

Paul,

I always read your posts as you have taught me some important and useful things
about compilers. Would you care to expand on this remark below? I always use
unsigned chars as return types on the MPS430, just as you say, assuming it uses
less space than words and will run faster. I use them as my default variable for
the same reason. Please tell us more.

Lloyd

--- In m..., "Paul Curtis" wrote:

> Quite what you'd want to use unsigned char as a return type on a 16-bit
> machine, I have no idea. If it is in the (mistaken) belief that smaller
> types generate "better code", this is not true on the MSP430.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> SolderCore running Defender... http://www.vimeo.com/25709426
>

> --- In m... ,
> "Paul Curtis" wrote:
>
>> Quite what you'd want to use unsigned char as a return type on a
>> 16-bit machine, I have no idea. If it is in the (mistaken) belief
>> that smaller types generate "better code", this is not true on the
>> MSP430.
>>

On 12/04/2012 23:29, lslonim2 wrote:
> Paul,
>
> I always read your posts as you have taught me some important and
> useful things about compilers. Would you care to expand on this
> remark below? I always use unsigned chars as return types on the
> MPS430, just as you say, assuming it uses less space than words and
> will run faster. I use them as my default variable for the same
> reason. Please tell us more.
>
> Lloyd
>

(I don't want to fuss, but please learn to bottom-post or intermingle
your reply with the earlier posts. It makes it far easier to follow the
thread of a conversation when you can read it in chronological order.)
First off, there is no such concept as an "unsigned char" (or a "signed
char"). Can show me the difference between a positive letter X and a
negative letter X? "char" is for characters, letters, and parts of
strings. The appropriate choice of type for 8-bit arithmetic values is
"uint8_t" or "int8_t" - these names say what you mean, so that the code
you write is clearer and more logical. The use of "unsigned char" as a
type is a hang-over from one of K&R's many bad language design
decisions, and should be avoided.
However, back to the point in question.

For the most part, an msp430 compiler will generate equally efficient
(small and fast) code for 8-bit data as for 16-bit data, as the
instruction set handles both sizes directly. You will occasionally get
extra instructions, such as a mask "and" when converting 16-bit to
8-bit, or a "sign extend" instruction when converting int8_t to int16_t.

You won't save anything by using 8-bit instead of 16-bit, except when it
is data saved in ram (or constant data in flash). Using 8-bit in ram
won't save code space or increase speed, but obviously it will save ram
space. That doesn't necessarily apply to stack frames for local
variables, as these will often be aligned to 16-bit anyway.

If you want to write code that is portable between 8-bit and 16-bit
processors and generates the most efficient code, use "int_fast8_t" and
"uint_fast8_t". On an 8-bit AVR, for example, these will be 8-bit types
- while on an msp430 they will be 16-bit.

mvh.,

David
> Return values use registers, not the stack - otherwise the compiler would
> have to generate code to swap the return address with the return value ...
> now calling parameters are pushed onto the stack - although Crossworks
> uses a register for the first calling parameter and the stack if there are
> additional parameters.

Actually, the CrossWorks compiler uses R15 through R12 for parameters,
fitting them in as it can. One 64-bit parameter will take all four
registers, four 16-bit parameters will take all four registers, and four
8-bit values will take all four registers as the parameters are passed using
the natural word width of the machine.

This is, of course, a simplification of the actual register assignment
method.

-- Paul.