Essential type of ~(uint16_t)0x30 - Printable Version +- MISRA Discussion Forums (https://forum.misra.org.uk) +-- Forum: MISRA C (https://forum.misra.org.uk/forumdisplay.php?fid=4) +--- Forum: MISRA C:2012 and MISRA C:2023 guidelines (https://forum.misra.org.uk/forumdisplay.php?fid=21) +---- Forum: 8.10 The essential type model (https://forum.misra.org.uk/forumdisplay.php?fid=165) +---- Thread: Essential type of ~(uint16_t)0x30 (/showthread.php?tid=1537) |
Essential type of ~(uint16_t)0x30 - grunwald - 09-04-2020 What is the essential type of "~(uint16_t)0x30" ? Going by Appendix D "Bitwise complement": * The operand is essentially unsigned * The operand is an integer constant expression * The result of "~(uint16_t)0x30" is -49 of standard type int (assuming int is 32 bits and twos complement). * The UTLR of -49 is ill-defined. Option 1: If the resulting constant is negative, convert it to the unsigned type corresponding to the expression's standard type, then use the UTLR of that converted value. This would result in "~(uint16_t)0x30" having essential type "unsigned int" (same as without the cast to uint16_t). Option 2: If the resulting constant is negative, treat the expression as if it was non-constant, using the essential type of the operand instead. This would result in "~(uint16_t)0x30" having essential type "uint16_t" (same as if 0x30 wasn't a compile-time constant). Option 3: If the resulting constant is negative, use the standard type for the essential type. This would result in "~(uint16_t)0x30" having essential type "signed int". This also affects other constant expressions producing negative values after integral promotion, e.g. "(uint16_t)300u - (uint16_t)301u". Re: Essential type of ~(uint16_t)0x30 - misra-c - 01-06-2020 This discussion assumes that "uint16_t" is a 16-bit unsigned short, and that "uint32_t" is a 32-bit unsigned int. Taking the operators in turn. (uint16_t)0x30 The result of the cast has an essential type of unsigned short and a value of 0x30 Appendix D on the ~ operator says: Quote:1. If the operand is essentially unsigned then: The operand is essentially unsigned and the operand is an integer constant expression, so option 1.1 is selected. Therefore the result is of the ~ operator has an essential type which is unsigned. The value of the result occupies 32-bits and so the essential type of the result is unsigned int. You are correct in saying that small unsigned types are promoted to a "signed int" standard type, but have an "essentially unsigned" type. This is only an issue if the resultant value is treated as a signed value, otherwise the bit pattern is consistent with what a user would expect. Any attempt to use the value of the result in an essentially signed context will produce a violation of rule 10.1, 10.3 or 10.4. Code: uint16_t u16 = ~(uint16_t)0x30; // Rule 10.3 violation - uint16_t v uint32_t The same argument follows for (uint16_t)300U - (uint16_t)301U. Appendix D on "-" paragraph 2.1 says Quote:"If the expression is an integer constant expression then the essential type of the result is the UTLR of the result;" |