相关疑难解决方法(0)

(为什么)使用未初始化的变量未定义行为?

如果我有:

unsigned int x;
x -= x;
Run Code Online (Sandbox Code Playgroud)

很明显,x 应该这样表达后是零,但到处看,他们说的行为,这种代码是不确定的,而不是仅仅值x(直到减法之前).

两个问题:

  • 这段代码的行为确实未定义吗?
    (例如,代码在兼容系统上崩溃[或更糟]?)

  • 如果是这样,为什么 C表示行为是未定义的,当非常清楚x这里应该为零时?

    即不在此定义行为给出的优势是什么?

很明显,编译器可以简单地使用它在变量中认为"方便"的任何垃圾值,并且它可以按预期工作......这种方法有什么问题?

c initialization undefined-behavior

77
推荐指数
6
解决办法
1万
查看次数

从未初始化的变量memcpy是未定义的行为吗?

是使用未初始化的变量作为srcmemcpy用C未定义行为?

void foo(int *to)
{
  int from;
  memcpy(to, &from, sizeof(from));
}
Run Code Online (Sandbox Code Playgroud)

c memcpy undefined-behavior language-lawyer

21
推荐指数
2
解决办法
1835
查看次数

为什么这个简单的赋值是未定义的行为?

我清楚了解了我对价值初始化与默认初始化的理解,并且发现了这个:

struct C {
    int x;
    int y;
    C () { }
};

int main () {
    C c = C ();
}
Run Code Online (Sandbox Code Playgroud)

显然这是UB,因为

在C()的情况下,有一个能够初始化x和y成员的构造函数,因此不会进行初始化.因此,尝试将C()复制到c会导致未定义的行为.

我想我理解为什么,但我不确定.有人可以详细说明吗?

这是否意味着这也是UB?

int x; x = x;
Run Code Online (Sandbox Code Playgroud)

顺便提一下,关于值初始化,以下是否保证为零?

int x = int ();
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior value-initialization

12
推荐指数
1
解决办法
348
查看次数

陷阱表示,unsigned char和IA64 NaT

来源:ia64上未初始化的垃圾可能致命

在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"部分的缺陷报告末尾添加上述内容是否处理此案例?

defect_report

以下函数在C90下具有未定义的行为,但在C99下似乎严格符合

  int foo(void) {
      unsigned char uc;
      return uc + 1 >= 0;
  }
Run Code Online (Sandbox Code Playgroud)

c

9
推荐指数
1
解决办法
455
查看次数

为什么 GCC 包含一个“空”的 XOR

我有以下一段代码:

typedef struct {
        int x;
        int y;
        int z;
        int w;
} s32x4;

s32x4
f() {
        s32x4 v;
        v.x = 0

        return v;
}
Run Code Online (Sandbox Code Playgroud)

生成(gcc -O2):

f:
        xor     eax, eax
        xor     edx, edx          ; this line is questionable
        ret
Run Code Online (Sandbox Code Playgroud)

其中 clang 输出(clang -O2):

f:                                      # @f
        xor     eax, eax
        ret
Run Code Online (Sandbox Code Playgroud)

问题

  • 有没有理由GCC插入XOR那里?
  • 如果没有充分的理由:我可以以某种方式摆脱它吗?

笔记

c assembly gcc x86-64 undefined-behavior

1
推荐指数
1
解决办法
178
查看次数