在C循环(铿锵VS海湾合作委员会)的数组值

问题描述:

我试图在c中的for循环播放数组初始化。在C循环(铿锵VS海湾合作委员会)的数组值

这里是我试过的程序:

#include<stdio.h> 
int main(){ 
for(int i=0;i<3;i++){ 
    for(int j=0;j<3;j++){ 
     int br[10]={0}; 
     printf("%d\n", br[-1]); 
    } 
} 

return 0; 
} 

这段代码的结果时,用gcc编译如下:

0 1 2 0 1 2 0 1 2 

时铿锵编译同样的程序,结果是:

0 0 0 0 0 0 0 0 0 

如果我通过在开始第二个lo之前进行数组初始化来调整程序OP:

#include<stdio.h> 


int main(){ 
for(int i=0;i<3;i++){ 
    int ar[10]={0}; 
    for(int j=0;j<3;j++){ 
     int br[10]={0}; 
     printf("%d\n", br[-1]); 
    } 
} 

return 0; 
} 

我得到的输出0 0 0 0 0 0 0 0 0对GCC和铛

谁能解释究竟是什么在这里发生的事情,当我尝试,为什么这些结果显示了这两个不同的访问负指数编译器(gcc和clang)以及为什么在第二次循环改变所有内容之前另一个数组初始化。

+3

'BR [-1]'是[未定义行为(https://en.wikipedia.org/wiki/Undefined_behavior)......这就是 – LPs

+0

我不这么认为。我认为这与内存分配有关。 – satishdd

+1

不,它是UB,纯粹而简单。编译器保留吃你的猫的权利。 – Bathsheba

br[-1]的行为是undefined

C标准没有定义试图将边界阵列的外部访问的元素的行为。 (有趣的是,主要是因为这个原因,为什么C被许多人视为一种“不安全”的语言)。您可以随时检查生成的汇编程序,以便全面分析编译器生成的内容。

Here is an example of using negative array idexes.

如果使用BR [-1]您在阵列之前打印元素:

some stuff | your array | more stuff 
X X X X X | 0 0 0 0 ...| X X X X 
     ^this element will be printed 

因此,在一个情况下,你也许有i或j的值,但在此之前数你的数组可以用不同的编译器或编译器选项来改变。

@Bathsheba 在我的链接最多的回答说,行为是C99§6.5.2.1/ 2定义的,但你不知道哪个变量位于您的阵列前方。

下标运算符[]的定义是E1 [E2]等于(*((E1)+(E2)))。