使用另一个数组为数组编制索引-gcc 6.3运行时错误

使用另一个数组为数组编制索引-gcc 6.3运行时错误,c,gcc,language-lawyer,C,Gcc,Language Lawyer,我读了一个关于导致运行时错误的代码的问题,例如seg错误 我试图用ideone.com调试代码,结果很奇怪 我已将代码精简到最低版本,以重现这种奇怪的行为。因此,代码没有做任何有意义的事情。代码的目的只是显示奇怪的行为 代码示例1: 看 使用的编译器是GCC 6.3 区别只是: .... a[s[r]] .... in example 1 及 所以问题是为什么第一个示例失败,第二个示例执行良好 我在代码中查找了UB,但找不到任何UB。代码中有UB吗 这是GCC 6.3中已知的错误吗 更新 正如

我读了一个关于导致运行时错误的代码的问题,例如seg错误

我试图用ideone.com调试代码,结果很奇怪

我已将代码精简到最低版本,以重现这种奇怪的行为。因此,代码没有做任何有意义的事情。代码的目的只是显示奇怪的行为

代码示例1:

使用的编译器是GCC 6.3

区别只是:

.... a[s[r]] .... in example 1

所以问题是为什么第一个示例失败,第二个示例执行良好

我在代码中查找了UB,但找不到任何UB。代码中有UB吗

这是GCC 6.3中已知的错误吗

更新

正如Scott Hunter正确指出的,这两个代码示例所做的并不相同


第一个示例由于UB而失败,因为变量r在while主体内变为-1,并且在while的下一个条件检查中,它访问s[-1]。例如,在两个版本中,r在while循环中发生变化;因此,在第一个版本中,与a[i]进行比较的a元素的索引发生变化,但在第二个版本中不发生变化。

在两个版本中,r在while循环中发生变化;因此,在第一个版本中,与a[i]进行比较的a元素的索引会发生变化,但在第二个版本中不会发生变化。

问题在于,在循环中,r变为-1。这就解释了。问题是r在循环中变成了-1。这就解释了。下次你想问一些小改动,你应该事先区分两个版本。下次你想问一些小改动,你应该事先区分两个版本。
#include <stdio.h>

int main() {
    int a[3] = {3, 2, 5};
    int s[3] = {0, 0, 0};
    int r = 0;
    int i;
    for(i = 1; i < 3; i++) {
        int t = s[r];                          // These 2 lines 
        while((a[i] < a[t]) && (r >= 0))       //
//        while((a[i] < a[s[r]]) && (r >= 0))  // instead of this line
        {
            r--;
        }
        printf("initialize s[%d] to %d\n", r+1, i);
        ++r;
        s[r] = i;
    }
    printf("%d\n", r);
    return 0;
}
initialize s[0] to 1
initialize s[1] to 2
1
.... a[s[r]] .... in example 1
int t = s[r];     in example 2
.... a[t] ....