This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/TMS320F28377D:针对 C99十六进制浮点运算、宏令牌连接断开

Guru**** 2589265 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/609667/compiler-tms320f28377d-macro-token-concatenation-is-broken-for-c99-hex-floats

器件型号:TMS320F28377D

工具/软件:TI C/C++编译器

以下代码不能使用 CGT 17.6.0.STS 编译(可能还有其他版本、我尚未选中)。

#define CONCATENATE ( a, b) a ##b
float A =+0x1.c801aap-2;
float b = CONCATENATE (+、0x1.c801aap-2);
float c = CONCATENATE (+0x1.、c801aap-2);
float d = CONCATENATE (+0x1.c801aa、p-2);

CCS 输出为:

****为项目 test_hexfloat_macro 构建配置调试****

"C:\\ti\\ccsv6\\utils\\bin\\gmake"-k all
'生成文件:./main.c'
'调用:C2000编译器'
"c:/ti/ccsv6/tools/compiler/ti-cgt-c2000_17.6.0.STS/bin/cl2000 -v28 -ml -mt --cla_support=cla1 -float_support=fpu32 -tmu_support=tmu0 -vcu_support=vcu2 -include_path="C:/ti/ccsv6/tools/compiler/ti-cgt-c2000_17.6.0.STS/include -g -diag_warning=225 -diag_wrap=off -display_error_number-preproc_prelisting_main_proc_prelisting_main_proc_main_proc_deconusing."

>>编译失败
subdir_rules.mk:7:目标'main.obj'的配方失败
"./main.c"、第3行:警告#1934-D:在宏"CONCATENATE"中与"0x1.c801aap-2连接不会创建有效的令牌
"./main.c"、第4行:错误#168:无效的浮点常量
"./main.c"、第5行:错误#168:无效的浮点常量
2在编译"./main.c"时检测到错误。
gmake:***[main.obj]错误1.
gmake:目标"全部"不会由于错误而重新生成。

****构建完成****

然而、预处理器列表表明、预处理器的输出在所有情况下都是相同的:

l 1 "../main.c"
n#define CONCATENATE (a、b) a ## b
Nfloat A =+0x1.c801aap-2;
w "./main.c" 3 11在宏"CONCATENATE"中与"0x1.c801aap-2连接不会创建有效的令牌
nfloat b = CONCATENATE (+、0x1.c801aap-2);
Xfloat b =+0x1.c801aap-2;
e "../main.c" 4 11无效的浮点常量
nfloat c = CONCATENATE (+0x1.、c801aap-2);
Xfloat c =+0x1.c801aap-2;
e "../main.c" 5 11无效的浮点常量
nfloat d = CONCATENATE (+0x1.c801aa、p-2);
Xfloat d =+0x1.c801aap-2;

预处理源(*。pp 文件)也意味着这种情况:

float A =+0x1.c801aap-2;
float b =+0x1.c801aap-2;
float c =+0x1.c801aap-2;
float d =+0x1.c801aap-2;

这里发生什么事了? 我是否违反了 C 预处理器标准?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我还不理解所有的细微差别。  但我可以告诉您、我没有找到任何接受该源代码的 C 编译器。  

    下面是当我尝试使用 GCC 版本5.4.0时的样子...

    $ gcc -c file.c
    file.c:3:24:错误:粘贴"+"和"0x1.c801aap-2 "不会提供有效的预处理令牌
    float b = CONCATENATE (+、0x1.c801aap-2);
    ^
    file.c:1:29:注:在宏‘CONCATENATE’
    #define CONCATENATE (a、b) a ## b 的定义中
    ^
    file.c:4:25:错误:指数没有数字
    浮点 c = CONCATENATE (+0x1.、c801aap-2);
    ^
    file.c:1:29:注:在宏‘CONCATENATE’
    #define CONCATENATE (a、b) a ## b 的定义中
    ^
    file.c:5:25:错误:指数没有数字
    浮点 d = CONCATENATE (+0x1.c801aa、P-2);
    ^
    file.c:1:29:注:在宏‘CONCATENATE’
    #define CONCATENATE (a、b) a ## b 的定义中
    ^μ A 

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尝试在 C99模式下编译它。 使用选项--c99
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    仔细观察 C99标准、十六进制浮点常量以0x 开头;值前面的+或-不是浮点常量令牌的一部分。 因此,您不能尝试使用##标记粘贴运算符添加前导+或-。 如果您需要具有正值的表达式、只需将+放在这里而不使用##运算符、如下所示:

    float b =+/*注意差距! */ 0x1.c801aap-2;

    至于其他行、需要##本身的两个操作数都是有效的预处理令牌。 此处所需的预处理令牌类型是 pp 数字(请参阅 C99第6.4.8节“预处理号码”)。 而0x1。 不是有效的十六进制浮点常量、它是有效的 pp 数。 但是、c801aap-2不是因为它以字母开头... 换句话说、如果第二个参数中的第一个数字不是十进制数字、则不能将十六进制数字与令牌粘贴相结合。

    GCC 同意 TI 编译器的意见、使用##无效。

    您尝试使用令牌粘贴解决了什么问题? 也许我们可以找到一种法律方法来写它?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们尝试编写可移植的十六进制浮点数、因为十进制浮点数的舍入是定义的实现方式。 我们的目标是 TI CGT 和 Msdev。 TI CGT 采用 C99十六进制浮点值。 Msdev 没有。 我们正在寻找一种使用符号、尾数和指数为 TI CGT 构建十六进制浮点数的方法。

    最后、我想我们将按照在 Msdev 中所需的方式使用 uint32s、在我们继续操作时将其重新解释为 float 值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我知道您需要一个编译时间常量、但您可能可以使用 UNION 和宏来根据需要设置位。

    这不可移植、可能不适用于此编译器。

    您也可以只使用单独的标头和 Plain #define
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、舍入是实现定义的、但在 TI (舍入到偶数)和 MS 之间、舍入模式可能是相同的。

    如果不接受十六进制浮点、我无法快速了解如何使用符号、十六进制尾数和十六进制指数在 MS 中构造浮点、但您可以在不粘贴令牌的情况下对 TI 执行类似操作。 解析器将对乘法进行三倍折叠。

    float x =+ 0x1.c801aap+0 * 0x1p-2
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Keith Barkley"]您可能可以使用 UNION 和宏来根据需要设置位。

    在此之前、请使用 TI 编译器尝试__u32_bits_as_f32 (0x3ee400d5)。  这不会经过内存、因此更便宜。