我遇到了下面的初始化,可以看出VS2012显示错误抱怨太多的初始化程序.在GCC中,它似乎返回第一个元素作为值.
为什么在GCC中支持这种特殊的初始化?
#include <stdio.h>
int main()
{
int q = {1,2};
char c = {'s','t','\0'}; /* c is 's' */
printf("%d\n",q); /* prints 1*/
}
Run Code Online (Sandbox Code Playgroud) 在ia64上,每个64位寄存器实际上是65位.额外的位被称为"NaT",代表"不是一件事".当寄存器不包含有效值时,该位置1.可以将其视为浮点NaN的整数版本.
NaT位最常见于推测执行.在ia64上有一种特殊形式的加载指令,它试图从内存中加载值,但是如果加载失败(因为内存被分页或地址无效),那么所有发生的事情都会发生,而不是引发页面错误是NaT位被设置,并继续执行.
NaT的所有数学运算都会再次产生NaT.
源文章接着解释了在推测加载期间寄存器如何最终具有NaT表示并发出以下注释:
对于你看,如果你有一个值为NaT的寄存器,并且你以错误的方式呼吸(例如,尝试将其值保存到内存中),处理器将引发STATUS_REG_NAT_CONSUMPTION异常.
似乎从陷阱表示的其他堆栈溢出答案,
"任何类型(unsigned char除外)可能有陷阱表示".
这个链接说明了
标准给出的关于访问未初始化数据的唯一保证是unsigned char类型没有陷阱表示,并且该padding没有陷阱表示.
如果这样的寄存器(具有NaT位设置的寄存器)被分配用于存储未初始化的无符号字符(类似于下面的缺陷报告中的代码片段),那么如何根据ISO C11处理?
以下缺陷报告是否指向同一问题,是否在ISO C11中得到纠正?
如果不是如何处理这种特殊情况?
如果左值指定了一个自动存储持续时间的对象,该对象可能已经使用寄存器存储类声明(从未使用过其地址),并且该对象未初始化(未使用初始化程序声明,并且未对其进行任何赋值)使用),行为未定义
在"更改为C1X"部分的缺陷报告末尾添加上述内容是否处理此案例?
以下函数在C90下具有未定义的行为,但在C99下似乎严格符合
int foo(void) {
unsigned char uc;
return uc + 1 >= 0;
}
Run Code Online (Sandbox Code Playgroud) main()
{
int a=10,b=30,c=0;
if( c =({a+b;b-a;}))
{
printf("%d",c);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么构造({;})在C中是合法的,为什么它返回最后一个语句值作为表达式的结果(为什么它与逗号运算符类似)?
在ISO C99中,非左值的数组仍然会衰减为指针,并且可能是下标的,尽管它们可能不会在下一个序列点之后被修改或使用.(来源)
我知道这个功能允许在函数返回包含数组的结构的情况下进行数组索引,这在C89中是不允许的(http://yarchive.net/comp/struct_return.html)
请你帮我理解为什么在下一个序列点之后使用/修改它有限制?
C参考手册指出"组件(尤其是位字段)被打包到结构中的精确方式取决于实现,但对于每个实现都是可预测的".
我读到一些编译器在Big endian机器中从左到右(MSB到LSB)包含位字段,而在Little endian机器中从右到左(LSB到MSB).
以两种不同的方式表示位域的原因/优势取决于字节顺序吗?