简体   繁体   English

警告:使用 -O3 标志编译时,数组下标高于数组边界 [-Warray-bounds]

[英]warning: array subscript is above array bounds [-Warray-bounds] when compiling using -O3 flag

I still cannot understand why I got this warning array subscript is above array bounds [-Warray-bounds] for a small C code as the following:我仍然不明白为什么我得到这个警告array subscript is above array bounds [-Warray-bounds]对于一个小的 C 代码,如下所示:

#include <stdio.h>
#include <string.h>

static int _memcmp( const void *x, const void *y, size_t size ){
    const char *s1 = (char*)x, *s2 = (char*)y;

    int ret;
    ret = s1[0] - s2[0];
    if ( size == 1 || ret != 0 )
        return ret;

    ret = s1[1] - s2[1];
    if ( size == 2 || ret != 0 )
        return ret;

    ret = s1[2] - s2[2];
    if ( size == 3 || ret != 0 )
        return ret;

    ret = s1[3] - s2[3];
    if ( size == 4 || ret != 0 )
        return ret;

    ret = s1[4] - s2[4];
    if ( size == 5 || ret != 0 )
        return ret;

    ret = s1[5] - s2[5];
    if ( size == 6 || ret != 0 )
        return ret;

    ret = s1[6] - s2[6];
    if ( size == 7 || ret != 0 )
        return ret;

    ret = s1[7] - s2[7];
    if ( size == 8 || ret != 0 )
        return ret;

    ret = s1[8] - s2[8];
    if ( size == 9 || ret != 0 )
        return ret;

    ret = s1[9] - s2[9];
    if ( size == 10 || ret != 0 )
        return ret;

//0-20
    ret = s1[10] - s2[10];
    if ( size == 11 || ret != 0 )
        return ret;

    ret = s1[11] - s2[11];
    if ( size == 12 || ret != 0 )
        return ret;

    ret = s1[12] - s2[12];
    if ( size == 13 || ret != 0 )
        return ret;

    ret = s1[13] - s2[13];
    if ( size == 14 || ret != 0 )
        return ret;

    ret = s1[14] - s2[14];
    if ( size == 15 || ret != 0 )
        return ret;

    ret = s1[15] - s2[15];
    if ( size == 16 || ret != 0 )
        return ret;

    ret = s1[16] - s2[16];
    if ( size == 17 || ret != 0 )
        return ret;

    ret = s1[17] - s2[17];
    if ( size == 18 || ret != 0 )
        return ret;

    ret = s1[18] - s2[18];
    if ( size == 19 || ret != 0 )
        return ret;

    ret = s1[19] - s2[19];
    if ( size == 20 || ret != 0 )
        return ret;

    return memcmp( s1 + 20, s2 + 20, size - 20 );
}

void t1(){
    char *x = "hihihaha";
    printf("%d\n", _memcmp( x, "ha", 2 ));
}

void t2(){
    char *x = "hihihaha";
    printf("%d\n", _memcmp( x, "hi", 2 ));
}
int main(){
    return 0;
}

When I compiled with 03 flag, I got this message:当我用03标志编译时,我收到了这条消息:

gcc-7 -O3 -Wall -o mem_cmp mem_cmp.c
mem_cmp.c: In function ‘_memcmp.part.0.constprop’:
mem_cmp.c:89:23: warning: array subscript is above array bounds [-Warray-bounds]
     return memcmp( s1 + 20, s2 + 20, size - 20 );

I've tried with gcc-4.9 and gcc-5 but no luck.我试过gcc-4.9gcc-5但没有运气。

Edit :编辑

I'm curious to know about why the warning appears rather than about the style of code.我很想知道为什么会出现警告而不是代码风格。 (I know well memcmp . Certainly _memcmp can be reimplemented by for but I want to gain even some cycles.) (我很了解memcmp 。当然_memcmp可以通过for重新实现for但我想获得一些循环。)

Your memcmp assumes that the memory s1+20 is within an array s1 - which it is not.您的memcmp假定内存s1+20位于数组s1 - 而事实并非如此。 Even if the compiler didn't complain about this - you would get into undefined behavior (which may range from crashing of your program to correct execution. This is not what you should reply on.).即使编译器没有抱怨这一点 - 您也会进入未定义的行为(这可能从程序崩溃到正确执行。这不是您应该回复的内容。)。 Mostly from the string literals size which is known at compile tile it infers about this.主要是从编译 tile 中已知的字符串文字大小中推断出这一点。

Correct one would be正确的一个是

return memcmp( s1, s2, min(strlen(s1),strlen(s2)));

where min(x,y) returns minimum of x and y .其中min(x,y)返回xy最小值。

First check the size and then access the array.首先检查大小,然后访问数组。 First do the size checking then index into the array.首先进行大小检查,然后索引到数组中。 repetitive code over here can be reduced using for loop.使用for循环可以减少这里的重复代码。 By that I mean whatever you are doing for different indices in those if statements can be packed into a single block, so that it can be used with for loop (with index variables denoting the changed value in each iteration).我的意思是,无论您为if语句中的不同索引做什么,都可以将其打包到单个块中,以便它可以与 for 循环一起使用(索引变量表示每次迭代中更改的值)。

Also note if you are using memcmp at last then don't go for checking characters individually - it is not needed.另请注意,如果您最后使用的是memcmp ,则不要单独检查字符 - 不需要。 You can just check it directly using memcmp and then output the result.您可以使用memcmp直接检查它,然后输出结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM