Type casting: double to char: multiple questions

核能气质少年 提交于 2021-02-10 10:41:47

问题


Consider this code:

#include <stdio.h>

int main(void) 
{
    /* TEST 1 */
    double d = 128;
    char ch = (char)d;
    printf("%d\n", ch);

    /* TEST 2 */
    printf("%d\n", (char)128.0);

    /* TEST 3 */
    char ch1 = (char)128.0;
    printf("%d\n", ch1);
    return 0;
}

Results:

        gcc*  clang*  cl*
TEST 1  -128  -128    -128
TEST 2  127   0       -128
TEST 3  127   -2      -128

* latest version

Questions:

  1. Why the results differ between tests (excluding cl)?
  2. Why the results differ between compilers (excluding TEST 1)?
  3. In case of UB/IB, where is the UB/IB exactly? What the standard says?
  4. [Extra question] Why clang shows so different behavior? Where these 0 and -2 come from?

回答1:


When CHAR_MAX == 127, (char)128.0 is undefined behavior (UB).

When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined. C17dr § 6.3.1.4 1

This is not UB due to integer overflow. It is UB due to conversion rules.




回答2:


AS @chux stated (char)128.0 is an UB. gcc because the triviality of the example detects this UB and instead takes CHAR_MAX as largest closest signed number.

But if you confuse it a bit it will not behave like this (conversion to int is not an UB, and the next conversion UB is not detected by the gcc).

int main(void) 
{
    volatile char x = (char)128.0;
    volatile char y = (char)(int)128.0;

    printf("%d %d\n", x, y);
}

and the code (the interesting part):

        mov     BYTE PTR [rsp+14], 127
        mov     BYTE PTR [rsp+15], -128

https://godbolt.org/z/xG3jUy

BTW this gcc behaviour was discussed long time ago and many people (including me) were opposing it. But gcc developers decided to go this way.



来源:https://stackoverflow.com/questions/62682244/type-casting-double-to-char-multiple-questions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!