标签: undefined-behavior

初始化是否需要左值到右值的转换?是`int x = x;`UB?

C++标准包含一个半着名的例子,在3.3.2中的"令人惊讶的"名称查找,"声明点":

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

这初始化x自身,(原始类型)未初始化,因此具有不确定的值(假设它是一个自动变量).

这实际上是未定义的行为吗?

根据4.1"左值到右值转换",对未初始化的值执行左值到右值的转换是未定义的行为.右手是否x接受这种转换?如果是这样,示例实际上会有未定义的行为吗?

c++ initialization undefined-behavior language-lawyer

55
推荐指数
2
解决办法
2411
查看次数

在C99中,f()+ g()未定义或仅仅未指定?

我以前认为在C99中,即使函数的副作用fg干扰,虽然表达式f() + g()不包含序列点,f并且g会包含一些,所以行为将是未指定的:要么f()之前调用f()之前的g()或g().

我不再那么肯定了.如果编译器内联函数(即使未声明函数,编译器可能决定这样做inline)然后重新排序指令,该怎么办?可能有人得到上述两种不同的结果吗?换句话说,这是未定义的行为吗?

这不是因为我打算写这种东西,而是在静态分析器中为这样的语句选择最佳标签.

c c99 undefined-behavior sequence-points unspecified-behavior

54
推荐指数
2
解决办法
1436
查看次数

何时访问指向"死"对象的指针有效?

首先,澄清一点,我不是在谈论解除引用无效指针!

考虑以下两个例子.

例1

typedef struct { int *p; } T;

T a = { malloc(sizeof(int) };
free(a.p);  // a.p is now indeterminate?
T b = a;    // Access through a non-character type?
Run Code Online (Sandbox Code Playgroud)

例2

void foo(int *p) {}

int *p = malloc(sizeof(int));
free(p);   // p is now indeterminate?
foo(p);    // Access through a non-character type?
Run Code Online (Sandbox Code Playgroud)

以上示例中的任何一个都会调用未定义的行为吗?

上下文

提出这个问题是为了回应这一讨论.建议是,例如,指针参数可以通过x86段寄存器传递给函数,这可能导致硬件异常.

根据C99标准,我们学习以下内容(强调我的):

[3.17] 不确定值 - 未指定的值或陷阱表示

然后:

[6.2.4 p2]当指向的对象到达其生命周期的末尾时,指针的值变得不确定.

然后:

[6.2.6.1 p5]某些对象表示不需要表示对象类型的值.如果对象的存储值具有这样的表示并且由不具有字符类型的左值表达式读取,则行为是未定义的.如果这样的表示是由副作用产生的,该副作用通过不具有字符类型的左值表达式修改对象的全部或任何部分,则行为是未定义的.这种表示称为 …

c pointers undefined-behavior language-lawyer

53
推荐指数
2
解决办法
2546
查看次数

std :: memcpy是否在不同的可复制类型之间是未定义的行为?

我一直在std::memcpy用来规避严格的混叠很长一段时间.

例如,检查a float,像这样:

float f = ...;
uint32_t i;
static_assert(sizeof(f)==sizeof(i));
std::memcpy(&i, &f, sizeof(i));
// use i to extract f's sign, exponent & significand
Run Code Online (Sandbox Code Playgroud)

但是,这次,我检查了标准,我还没有找到任何可以验证这一点的东西.我所发现的是这个:

对于平凡可复制类型T的任何对象(可能重叠的子对象除外),无论对象是否保持类型T的有效值,组成对象的基础字节([intro.memory])都可以复制到char,unsigned char或std :: byte([cstddef.syn])数组.40如果将该数组的内容复制回对象,则该对象应随后保持其原始值.[例如:

#define N sizeof(T)
char buf[N];
T obj;                          // obj initialized to its original value
std::memcpy(buf, &obj, N);      // between these two calls to std?::?memcpy, obj might be modified
std::memcpy(&obj, buf, N);      // at this point, each subobject of obj of scalar …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing undefined-behavior language-lawyer c++17

52
推荐指数
3
解决办法
2898
查看次数

如果要在多个平台上部署,未定义的行为只是一个问题吗?

围绕未定义行为(UB)的大多数对话都讨论了如何有一些平台可以做到这一点,或者一些编译器会这样做.

What if you are only interested in one platform and only one compiler (same version) and you know you will be using them for years?

Nothing is changing but the code, and the UB is not implementation-defined.

Once the UB has manifested for that architecture and that compiler and you have tested, can't you assume that from then on whatever the compiler did with the UB the first time, it will do that every time?

Note: I …

c++ undefined-behavior

51
推荐指数
5
解决办法
3216
查看次数

C#中具有未定义行为的代码

在C++中,有很多方法可以编写编译的代码,但会产生未定义的行为(维基百科).C#中有类似的东西吗?我们可以用编译的C#编写代码,但是有未定义的行为吗?

c# c++ undefined-behavior

50
推荐指数
4
解决办法
4080
查看次数

Do std::min(0.0, 1.0) and std::max(0.0, 1.0) yield undefined behavior?

The question is pretty clear. The following gives the reason why I think these expressions might yield undefined behavior. I would like to know whether my reasoning is right or wrong and why.

Short read:

(IEEE 754) double is not Cpp17LessThanComparable since < is not a strict weak ordering relation due to NaN. Therefore, the Requires elements of std::min<double> and std::max<double> are violated.

Long read:

All references follow n4800. Specifications of std::min and std::max are given …

c++ floating-point undefined-behavior c++-standard-library language-lawyer

50
推荐指数
2
解决办法
1287
查看次数

这是编译器优化错误还是未定义的行为?

我们有一个烦人的错误,我无法解释这段代码:

unsigned char bitmap[K_BITMAP_SIZE] = {0} ;
SetBit(bitmap, K_18); // Sets the bit #18 to 1

for(size_t i = 0; i < K_END; ++i)
{
    if(TestBit(bitmap, i)) // true for 18
    {
        size_t i2 = getData(i); // for 18, will return 15
        SetBit(bitmap, i2); // BUG: IS SUPPOSED TO set the bit #15 to 1
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 它发生在Visual C++ 2010上
  2. 它发生在32位和64位版本上
  3. 它仅在发布版本上发生(设置为"最大化速度(/ O2)")
  4. 它不会仅在"最小化大小(/ O1)"设置的发布版本中发生
  5. 只有当我们__forceinline使用getData函数时才会在Visual C++ 2008上发生(默认情况下,VC++ 2008不会内联该函数,而VC++ 2010会这样做)
  6. 它发生在下面给出的代码片段上,可能是因为循环内部有大量内联
  7. 如果我们删除循环并直接设置有趣的值就不会发生(18)

奖金信息:

1- BenJ评论说这个问题没有出现在Visual C++ 2012上,这意味着这可能是编译器中的一个错误

2-如果我们 …

c++ visual-studio-2010 compiler-optimization undefined-behavior visual-studio

48
推荐指数
2
解决办法
2939
查看次数

浮点除零的行为

考虑

#include <iostream>
int main()
{
    double a = 1.0 / 0;
    double b = -1.0 / 0;
    double c = 0.0 / 0;
    std::cout << a << b << c; // to stop compilers from optimising out the code.    
}
Run Code Online (Sandbox Code Playgroud)

我一直认为这a将是+ Inf,b将是-Inf,并且c将是NaN.但我也听到传言说严格来说浮点除零的行为是未定义的,因此上面的代码不能被认为是可移植的C++.(理论上,这会消除我的百万行加上代码堆栈的完整性.糟糕.)

谁是对的?

注意我对实现定义感到满意,但我在谈论吃猫,在这里恶魔打喷嚏的未定义行为.

c++ floating-point divide-by-zero undefined-behavior language-lawyer

48
推荐指数
5
解决办法
1万
查看次数

通过从本地C风格的数组返回指针来获取悬空指针

我对以下代码感到有点困惑:

#include <iostream>

const char* f()
{
    const char* arr[]={"test"};
    return arr[0];
}

int main()
{
    auto x = f();
    std::cout << x;
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这段代码应该是UB(未定义的行为).我们返回一个指向本地范围内的C风格数组元素的指针.事情应该出问题.但是,我测试过的编译器都没有抱怨(我用过-Wall -Wextra -pedanticg ++和clang).valgrind也不抱怨.

上面的代码是有效的还是人们会想到的UB?

PS:运行它似乎产生"正确"的结果,即显示"测试",但这并不表示正确性.

c++ memory pointers undefined-behavior

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