On 6/1/2010 12:57 PM, mohangupta13 wrote:

> Well i had a though time extracting information from previous threads

> on the above three topics ....its soo much information and it creates

> more confusion ...

> kindly guide me to some well written articles on these topics...

> 1. Integral promotion :

>

> What i understand: " If two types are intermixed then the type with

> smaller capacity is promoted to the type with the larger capacity" ..i

> am sure i am wrong here .
What you've described is, loosely, the "usual arithmetic

conversions." Most arithmetic operators in C require that their

operands be of the same type, because most CPU's on which C code

runs have a similar requirement. Few CPU's can add an int to a

double, or compare a long to a short; they can add two doubles or

compare two longs, but can't work directly with mixed types.

When you as a programmer need to add an int to a double, what

must you do? You could convert the double to an int and add the

two ints, or you could convert the int to a double and add the two

doubles, or you could convert both operands to long double and add

those, or ... The usual arithmetic conversions tell you what C

will do when presented with mixed operands (I'm considering only

the arithmetic operands here, not pointers):

- If either is a long double, the other converts to long double.

- Otherwise, if either is a double, the other converts to double.

- Otherwise, if either is a float, the other converts to float.

- Otherwise, both operands are integers of some kind, and the

story continues below ...

There's also something called the "integer promotions," which

exist because many CPU's can perform arithmetic only on integers of

a few "widths." For example, a CPU that does all integer arithmetic

in registers may have no instructions for doing arithmetic on char

values: You fetch the char into a register (widening it as you go),

do the arithmetic in the wide register, and store (part of) the

result back in the char variable again. The integer promotions are

C's description of this kind of conversion (which happens almost

every time "narrow" integer is used, not just with mixed types):

- If the integer is "narrower" than int *and* if the range of

int includes the entire range of the original type, the

integer converts to (promotes to) int.

- If the integer is "narrower" than int *and* if some values

of the original type are out of range for int, the integer

converts to unsigned int.

- All other integer types (including int and unsigned int

themselves) are left unpromoted.

We return now to the usual arithmetic conversions, where we've

already covered the floating-point cases and are left with operands

of integer types. C applies the integer promotions to both operands,

which may resolve the type mismatch right there: a char and a short

might both promote to int, for example, and the types are no longer

mixed (it needn't always happen this way; see below). But if a

mismatch still exists:

- If both operand types have the same "signedness" -- both signed

or both unsigned -- the "narrower" operand converts to the type

of the "wider."

- Otherwise, we have one signed and one unsigned type. If the

signed type is "narrower" than the unsigned type, the signed

operand converts to the unsigned type. (This will change the

numeric value if the signed operand was negative.)

- Otherwise, if the range of the signed type includes all possible

values of the unsigned type, the unsigned type converts to the

signed type.

- Otherwise, we've got a signed type that is "wider" than the

unsigned type but can't represent all values of the unsigned

type. (This sounds like a contradiction, but it's not C's

fault: I've been using terms like "wide" and "narrow," and

they're just loose terms. The formal definition of C uses a

scheme of "integer conversion ranks" to describe this stuff

precisely, but I thought that dragging that intricate business

in would be more confusing than enlightening. Stick with "wide"

and "narrow" for now, and promise yourself that you'll look up

"integer conversion rank" later, when you're more secure.)

Anyhow, if we get to this seemingly contradictory situation,

both operands convert to the unsigned type of the same width

as the signed type (e.g., long + uint64_t might promote both

operands to unsigned long).

... and *that* covers both the usual arithmetic conversions and

the integer promotions. I've simplified a bit by using "wide" and

"narrow" and waving my hands a little, and I've also ignored complex

arithmetic, but I hope it's enough to get you started.

> 2. Sign extension:

>

> what i understand: whenever say a char is promoted to int the msb of

> char is copied in the extra bits in the msb of the int ...i.e char=

> 10010111---> 1111111110010111 (in int)...
Only on some machines. There are three things going on here:

First, each system makes its own decision as to whether plain char

is a signed type or an unsigned type. Since promoting an unsigned type

to a wider type (signed or unsigned) preserves the value, the sign

extension you describe won't happen on a system that chooses to treat

char as unsigned.

Second, each system makes its own decision about how to represent

negative integers. By far the most common is the two's complement

scheme you illustrate, but C also allows two other schemes, ones'

complement and signed magnitude. In a signed magnitude scheme, the

sign bit simply "relocates" during widening; it doesn't "propagate."

Third, each system makes its own decision about how wide the

various integer types are. There are some limits on what can be

chosen, but it is possible for char and int to have the same width

(this is said to be common practice in CPU's that specialize in digital

signal processing). On such a system, if char is taken to be unsigned,

a review of the integer promotions above will show that char promotes

to unsigned int, not to int. So you've got an unsigned char that

promotes to an unsigned int -- unsigned all the way, so there's no

"sign" to be manipulated in the first place.

> 3. Unsigned or signed character : what i understand is that if you

> declare char a=10; then 'a' is supposed to be signed character by

> default as no explicit unsigned qualifier was attached ..but some

> threads say its implementation define ...confusion here???
The signedness of plain char is implementation-defined, as

mentioned above. This is C's recognition of the fact that some

CPU's like to treat characters as small signed integers, while

others treat them as little bunches of bits, nominally unsigned.

If you're using char to store numeric data (as opposed to things

that are notionally "just character codes,") you should probably

specify signed char or unsigned char, since unadorned char will

behave differently on different systems.

--

Eric Sosman

http://www.velocityreviews.com/forums/(E-Mail Removed)lid