相关疑难解决方法(0)

在循环中的什么时候整数溢出变成未定义的行为?

这是一个例子来说明我的问题,其中涉及一些我不能在这里发布的更复杂的代码.

#include <stdio.h>
int main()
{
    int a = 0;
    for (int i = 0; i < 3; i++)
    {
        printf("Hello\n");
        a = a + 1000000000;
    }
}
Run Code Online (Sandbox Code Playgroud)

这个程序在我的平台上包含未定义的行为,因为它a会在第3个循环中溢出.

这是否会使整个程序具有未定义的行为,或者仅在溢出实际发生之后?编译器是否可能a 会解决溢出问题,因此它可以声明整个循环未定义,并且不会打扰运行printfs,即使它们都在溢出之前发生?

(标记为C和C++,即使它们不同,因为如果它们不同,我会对这两种语言的答案感兴趣.)

c c++ integer-overflow undefined-behavior

85
推荐指数
7
解决办法
1万
查看次数

未定义的未定义行为如何?

我不确定我是否完全理解未定义行为可能危及程序的程度.

假设我有这段代码:

#include <stdio.h>

int main()
{
    int v = 0;
    scanf("%d", &v);
    if (v != 0)
    {
        int *p;
        *p = v;  // Oops
    }
    return v;
}
Run Code Online (Sandbox Code Playgroud)

这个程序的行为是否针对v非零的情况而定义,或者即使v为零也未定义?

c undefined-behavior language-lawyer

34
推荐指数
3
解决办法
1759
查看次数

是否定义了在无法到达的路径上具有未定义行为的程序的行为?

考虑

void swap(int* a, int* b)
{
    if (a != b){
        *a = *a ^ *b;
        *b = *a ^ *b;
        *a = *a ^ *b;
    }   
}

int main()
{
    int a = 0;
    int b = 1;
    swap(&a, &b); // after this b is 0 and a is 1
    return a > b ? 0 : a / b;
}
Run Code Online (Sandbox Code Playgroud)

swap 试图欺骗编译器不优化程序.

是否定义了此程序的行为?a / b是永远无法达到的,但如果是,那么你会得到除零.

c undefined-behavior language-lawyer

24
推荐指数
2
解决办法
1798
查看次数

为什么即使使用constexpr索引,编译器也允许越界数组访问?

例如,如果我们有一个std::array并且我们使用constexpr编译器实例化一个超出绑定的元素将不会报告错误:

constexpr int EvaluateSpecialArrayIndex(int a)
{ return a * sizeof(int); }

array<int, 5> arr;

cout << arr[98] << endl; //compiles fine

cout << arr[EvaluateSpecialArrayIndex(4)] << endl; //the same as above
Run Code Online (Sandbox Code Playgroud)

我们不能以某种方式限制这个吗?

c++ arrays constexpr c++14 c++17

10
推荐指数
3
解决办法
1579
查看次数

可以保证UB在编译时被拒绝吗?

考虑这个程序:

#include <stdio.h>

int main(void)
{
    int x;
    while ( 1 == scanf("%d", &x) )
        printf("%c\n", "hello"[x]);
}
Run Code Online (Sandbox Code Playgroud)

编译器必须成功编译,因为程序没有UB,只要用户不输入范围之外的任何数字0- 4.

但是,根据这个线程, UB可以及时返回.现在考虑这个程序:

int main(void)
{ 
    printf("hello\n");
    "hello"[6];
}
Run Code Online (Sandbox Code Playgroud)

对此程序的任何调用都会导致未定义的行为,并且因为这可能是时间旅行,所以此程序在任何调用中的整个行为都是未定义的.因此,编译器可以拒绝该程序而不生成可执行文件吗?(我们可能会说UB回到编译阶段!)

c c++ undefined-behavior language-lawyer

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

是否可以获得UB代码是否可以保证?

我有一个代码片段从这里:

volatile int volatileInt;
int usualInt;

void function (unsigned x, unsigned y, unsigned z)
{
    volatileInt = 0;
    usualInt = (x % y) / z;
}

int main()
{
    function(rand(), rand(), rand());
}
Run Code Online (Sandbox Code Playgroud)

我使用Visual C++ 10编译/O2并获得此反汇编:

00403940  push        ebx  
00403941  push        esi  
   276:     function(rand(), rand(), rand());
00403942  mov         esi,dword ptr [__imp__rand (4050C0h)]  
00403948  push        edi  
00403949  call        esi  
0040394B  mov         edi,eax  
0040394D  call        esi  
0040394F  mov         ebx,eax  
00403951  call        esi  
00403953  xor         edx,edx  
00403955  div         eax,ebx …
Run Code Online (Sandbox Code Playgroud)

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

6
推荐指数
2
解决办法
143
查看次数