Originally posted by indepe
View Post
You can have the right to left and left to right ranking boost in case of equal. Yes both valid under the C Standard to use because this was not defined as invalid to use this is true undefined behaviour. This is what makes reading the standard you also have to be reading between the lines looking for the items that should have been defined that were not.
So signed and unsigned being equal in rank end up go back to order of operation ranking in some cases.
Signed==unsigned stuff gets fun is the compiler a left to right or a right to left ranking boost or no boost. Left to right boost Signed here is now higher than unsigned yes right to left is unsigned is now higher than signed. All three options are valid under the C standard.
This cursed here is not absolutely forbin by C11 or even newer versions of the C standard. Rank boost should be forbin.
Now we into the bits of evil written into the C standard itself.
No two signed integer types shall have the same rank, even if they have the same representation.
The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.
So you can have a ranking table that looks like the following.
Greatest rank at top least the bottom with the rank number next to them with the higher number being higher rank
3 unsigned int
3 signed int
2 unsigned
2 signed
1 int
Yes you would have been hoping for
4 unsigned
4 unsigned int
3 int
2 signed
1 signed int.
Both are technically lists correct to standard. Yes first list allows some really creative screw ups.
Yes is not the corresponding type to unsigned int, signed int and unsigned is signed right that is what is leading to the first wacky list generation..
Yes the two signed integers types being forbid from having the same rank and that the unsigned has to have equal or greater rank to its signed equal is what can generate the first rank list stupidity when equal is used instead of greater for the unsigned.
Lets get into the third bit cursed or the second bit of cursed written into the standard C.
These that you used are type defines not in fact covered by the C standard ranking clearly so the compiler could have shoved them into a stupid location that can be dependant on what order they were declared in the header files. Wrong placement int64_t could have end up with a higher rank than uint64_t. How do you declare in C that uint64_t is the corresponding type to int64_t that right you don't. Yes the C standard does not clearly define how typedef are in fact added to the rank system so welcome to another bit of undefined behaviour where the compiler is valid todo anything to you. Yes the fact you used uint64_t int64_t brings fun as these are technically extended integer type.
The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
So you have a unsigned int in gcc that 32 bit and you have uint32_t and you do the following.
Code:
signed int si = -1; uint32_t ui = ~0; if(si == ui) if(si != ui)
Rank system for type conversion in C is cursed. Seams fine until you attempt to follow the rules and generate stupidity of course sometimes compiler developers do this as the following blog demos.
Yes as noted here there are gcc out modified by different parties that instead correctly transforming the signed value to unsigned it will transform to unsigned to signed if there is no cast. Yes this is a pure problem ubuntu screwed up the rank in that blog but other parties have done it.
The reality is do not trust C rank system for type conversion to handle signed conversion correctly ever. Its not written into the C standard correctly to start off with to make sure that signed conversion is always right. There are so many ways where the conversion can go the wrong way of unsigned to signed its not funny and be perfectly valid to C standard.
Leave a comment: