令我惊讶的是,这段代码与gcc 11.4.0一起编译,i变成了0:

#include <stdio.h>

int     main( int argc, char *argv[] )
{
        int i = 1i;
        printf( "i = %d\n", i );
        return 0;
}

我try 在谷歌上搜索后缀i,但没有成功.我发现在每一个描述中只提到了常见的描述(例如,在对that SO question的回答中)

我还try 过所有低位字符和其他正值,发现j的行为相同,但我的变量值始终是0.带有其他后缀,例如a、b.它不会编译.

那么我偶然发现了什么呢?有没有方法可以阻止gcc编辑它,或者至少进行某种诊断?在"现实世界源代码"中,这种情况发生是由于简单的拼写错误,当然会导致运行时错误

推荐答案

GNU docs:

编写辅助数常数的简单方法是附加 后缀"i"或"I",或"j"或"J",为一个整数或浮点 常数例如,2.5fi具有类型_Complex float3i具有类型 _Complex int.四个替代后缀字母都是等效的.标准C不支持后缀"i"或"j".

所以我们可以得出结论:

  • ISO C标准不支持ijJ个后缀.这些后缀是海湾合作委员会扩展.ISO C确实支持虚部I,尽管对编译器来说对complex.h和复数的支持是可选的.如果编译器不支持__STDC_NO_COMPLEX__,则可以定义__STDC_NO_COMPLEX__.@Lundin

  • ijIJ等效.

  • 将上述任何后缀附加到一个等于数的常数.

Clang也支持这个NU扩展.

编译-pedantic-errors次失败:

$ gcc c.c -pedantic-errors -o c
c.c: In function 'main':
c.c:5:17: error: imaginary constants are a GCC extension
    5 |         int i = 1i;
      |                 ^~

$ clang c.c -pedantic-errors -o c
c.c:5:17: error: imaginary constants are a GNU extension [-Werror,-Wgnu-imaginary-constant]
        int i = 1i;
                ^
1 error generated.

另请参阅:What compiler options are recommended for beginners learning C?.

至于为什么i变成了0:

来自6.3.1.7关于真实和复杂转换的ISO C Standard个部分:

当实类型的值转换为复合类型时,复合类型的实部分 结果值由转换为相应实类型的规则确定,并且复结果值的虚部是正零或无符号零.

当复类型的值转换为实类型时,会丢弃复值的虚部,并根据相应实类型的转换规则转换实部的值.

因此,当你将1i分配给int时,它就会变成0,因为那是1i的实部,而虚部被丢弃.

截至后缀ab等,ISO C标准和GNU C标准都不支持任何此类内容.

C++相关问答推荐

错误:八进制常数中的数字9无效

是否可以在C中进行D3 D12申请?

自定义malloc实现上奇怪的操作系统依赖行为

为什么PLT表中没有push指令?

了解一些CLIPS原语数据类型

如何在C中使printf不刷新标准输出?

试图从CSV文件中获取双精度值,但在C++中始终为空

使用TCL C API导航到列表中的元素

如何仅使用软件重新初始化STM32微控制器中的USB枚举?

在编写代码时,Clion比vscode有更多的问题指示器

通过描述符查找文件路径时出现问题

当b是无符号字符时,int a=(b<;<;2)>;>;2;和int a=b&;0x3F;之间有什么区别?

将数组插入数组

不使用任何预定义的C函数进行逐位运算

从CentOS 7到Raspberry PI 2B的交叉编译-无法让LIBC和System Include标头一起工作

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

浮动目标文件,数据段

Tcl_GetDoubleFromObj在列表的迭代中是一个缺点

C 和 C++ 标准如何告诉您如何处理它们未涵盖的情况?

C/C++编译器可以在编译过程中通过按引用传递来优化按值传递吗?