Hi, I just signed in to this excellent network.
I hope I could get some answers to many questions
I have in writing C compilers.
My first question is:
Is "integer demotion" required in ANSI-C?
Assumption:
- CPU: 32-bit RISC (int = long = 4 bytes, short = 2 bytes, char = 1 byte)
- All integral operations done on 4 bytes (signed or unsigned int)
- Each 32-bit register holds one integral type data that is
"already" integer promoted, so that arithmetic conversion is
unnecessary when used as operands in integral operations.
- Integer demotion on mem-store and integer promotion on mem-load is
handled by the memory interface hardware. So if you save a short integer to
memory, and then read it back, it will have correct "already integer promoted"
bit pattern in the register.
The question here is: do I need to perform integer demotion where the destination is another register?
Example 1:
char i;
for(i = 0; i < n; i = i + 1){...}
Here, "char i" would most likely be allocated to internal register.
Then integer demotion for (i = i + 1) would require the below code sequence:
(tmp: signed int register)
tmp = i + 1;
tmp = tmp << 24;
tmp = tmp >> 24;
i = tmp;
Such integer demotion seems redundant since:
- if(n < 128): i never overflows
- if(n >= 128): (i < n) will always be true (infinite loop: must be a bug??)
Unless the latter case is the actual intention of the programmer,
I don't want to produce such integer demotion code here.
Example 2:
char c = val;
if(c < val)
Here, the intention can be:
- simply checking the sign of val (programmer assumes -128 <= val < 128)
- checking the bit-7 of val
If the former case is guaranteed, then integer promotion is unnecessary.
Example 3:
unsigned char c = val;
<c used in other integral operations>
Here, the intention COULD be the mask operation: c = val & 0xff; in which case
the programmer expects the integer demotion code here.
In Microsoft's C reference, it says:
"When the value with integral type is demoted to a signed integer with
smaller size, or an unsigned integer is converted to its corresponding
signed integer, the value is unchanged if it can be represented in the
new type. ... If it cannot be represented, the result is implementation-defined."
This seems to suggest that for my assumed RISC (where register holds integer
promoted values), integer demotion is unnecessary. But I have checked that
Microsoft's Visual-C does actually perform integer demotion in my first
for-loop example. My guess is that this is true for most other compilers.
So, to summarize my question:
- Is "integer demotion" required in ANSI-C?
- If not, as a compiler writer, is it "reasonable" to say to the programmers
"it's your responsiblity to make sure the values assigned to short integers
can fit into that short type, because with my compiler, "integer demotion"
may or may not be performed (depending on the destination (register or memory)"??
I appreciate any inputs on this issue.
Regards, tsuyois