Tag: undefined behavior

对未初始化变量的任何保证?

有许多声称使用未初始化的变量会调用未定义的行为(UB) 。 仔细阅读文档,我无法validation该声明,所以我想要一个令人信服的论点,为C和C ++澄清这一点。 我期望两者都有相同的语义,但我准备对微妙或不那么微妙的差异感到惊讶。 使用未初始化变量开始的一些示例。 请根据需要添加其他人,以解释他们未涵盖的任何角落案例。 void test1() { int x; printf(“%d”, x); } void test2() { int x; for(int i = 0; i < CHAR_BIT * sizeof x) x = x << 1; printf("%d", x); } void test3() { unsigned x; printf("%u", x); /* was format "%d" */ } void test4() { unsigned […]

内联x86程序集中是否未定义整数溢出?

说我有以下C代码: int32_t foo(int32_t x) { return x + 1; } 当x == INT_MAX时,这是未定义的行为。 现在说我用内联汇编代替了: int32_t foo(int32_t x) { asm(“incl %0” : “+g”(x)); return x; } 问题:当x == INT_MAX时,内联汇编版本是否仍会调用未定义的行为? 或者未定义的行为仅适用于C代码?

是否对空指针未定义行为执行算术运算?

它在我看来像下面的程序计算一个无效的指针,因为除了赋值和比较的平等之外, NULL是没有好处的: #include #include int main() { char *c = NULL; c–; printf(“c: %p\n”, c); return 0; } 然而,似乎GCC或Clang针对未定义行为的警告或工具都没有说这实际上是UB。 这个算术实际上是否有效,而且我太迂腐了,或者这是我们应该报告的检查机制的缺陷吗? 测试: $ clang-3.3 -Weverything -g -O0 -fsanitize=undefined -fsanitize=null -fsanitize=address offsetnull.c -o offsetnull $ ./offsetnull c: 0xffffffffffffffff $ gcc-4.8 -g -O0 -fsanitize=address offsetnull.c -o offsetnull $ ./offsetnull c: 0xffffffffffffffff 似乎很好地记录了Clang和GCC使用的AddressSanitizer更侧重于解除坏指针的引用,所以这很公平。 但其他检查也没有抓住它: – / 编辑 :我问这个问题的部分原因是-fsanitize标志能够动态检查生成的代码中的良好定义。 这是他们应该抓住的东西吗?

具有未定义结果的C代码,编译器生成无效代码(使用-O3)

我知道当你在C程序中做某些事情时,结果是不确定的。 但是,编译器不应该生成无效 (机器)代码,对吧? 如果代码做错了,或者代码生成了段错误或其他什么,那将是合理的…… 这应该根据编译器规范发生,还是编译器中的错误? 这是我正在使用的(简单)程序: int main() { char *ptr = 0; *(ptr) = 0; } 我正在使用-O3编译。 这不应该生成无效的硬件指令,对吧? 使用-O0 ,运行代码时会出现段错误。 这看起来更加明智。 编辑:它正在生成一个ud2指令……

C中未初始化的变量

我有点困惑。 据我所知,如果你在C中声明一个int,而不是初始化它,例如: int x; 所以它的价值是不确定的。 因此,如果我们尝试使用它或应该有未定义的行为。 所以如果我在VS2010中运行以下代码它会使程序崩溃。 int main(){ int a; printf(“%d\n”,a); return 0; } 现在让我们来看看下一个代码,它不提供任何警告而且不会崩溃 (为什么?) void foo(int *var_handle){ // do nothing } int main(){ int a; foo(&a); printf(“%d\n”,a); // works, prints some big value return 0; } 你能解释一下这种行为吗? 我们只添加了对一个什么都不做的函数的调用,但现在程序不会崩溃。

这是否会调用未定义的行为?

考虑以下C程序: #include int main(){ int a =-1; unsigned b=-1; if(a==b) printf(“%d %d”,a,b); else printf(“Unequal”); return 0; } 在行printf(“%d %d”,a,b); , “%d”用于打印无符号类型。 这会调用未定义的行为吗?为什么?

是否未定义行为抛弃函数参数的常量?

想象一下,我有这个C函数(以及头文件中的相应原型) void clearstring(const char *data) { char *dst = (char *)data; *dst = 0; } 在上面的代码中是否存在未定义的行为, 将const掉 ,或者它只是一个非常糟糕的编程实践? 假设没有使用const限定对象 char name[] = “pmg”; clearstring(name);

Turbo C ++:为什么printf在没有传递变量的情况下打印期望值?

在多项选择测试中提出了一个问题:以下程序的输出结果如何: #include int main(void) { int a = 10, b = 5, c = 2; printf(“%d %d %d\n”); return 0; } 选择是10,5和2的各种排列。出于某种原因,它适用于我们在大学时使用的Turbo C ++。 但是,在使用gcc(在启用-Wall时发出警告)或clang(启用了-Wformat并在默认情况下发出警告)或在Visual C ++中编译时,它不会。 正如预期的那样,输出是垃圾值。 我的猜测是它与Turbo C ++是16位,在32位Windows XP上运行这一事实有关,或者TCC在标准方面很糟糕。

减少指针超出范围; 将其增加到边界

以下是否会在第4行和/或第5行中引发未定义的行为: #include int main(void) { char s[] = “foo”; char * p = s – 1; /* line 4 */ printf(“%s\n”, p + 1); /* line 5 */ return 0; }

C – 是不确定的不确定值吗?

根据这篇文章 ,不确定的价值是: 3.17.2 1 indeterminate value either an unspecified value or a trap representation 根据谷歌的说法,不确定性的定义是: 不确定,已知或已建立 遗憾; 模糊。 根据字典,可确定的是: 能够被确定 根据merriam-webster,确定(在特定的上下文中)是: 通过调查,推理或计算找出或做出决定 因此,常识规定尽管在编译期间不确定值是未知的,但它在运行时是完全可确定的,例如,您总是可以读取占用该内存位置的任何事件。 或者我错了? 如果是这样,为什么? 编辑:为了澄清,我发布了与用户试图说服不确定值不确定的用户的激烈争论,我非常怀疑。 编辑2:澄清,通过“可确定”我并不意味着稳定或可用的值,即使它是未初始化的内存的垃圾值,仍然可以确定该垃圾的价值。 我的意思是试图确定这个价值仍然会产生一些价值,而不是……没有行动。 所以这个值必须来自一些内存,分配为仍然不确定的值的存储,我高度怀疑编译器实际上会使用一个随机数生成器只是为了提出一些任意值。