警告:使用-O3标志进行编译时,数组下标位于数组边界[-Warray-bounds]之上

时间:2018-02-20 17:17:48

标签: c arrays bounds

我仍然无法理解为什么我收到一条小C代码警告array subscript is above array bounds [-Warray-bounds]如下:

#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;
}

当我用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 );

我已尝试使用gcc-4.9gcc-5,但没有运气。

修改

我很想知道警告出现的原因而不是代码的样式。 (我很清楚memcmp。当然_memcmp可以for重新实现,但我想获得一些周期。)

1 个答案:

答案 0 :(得分:1)

您的memcmp假设内存s1+20位于数组s1内 - 它不是。即使编译器没有抱怨这一点 - 你会遇到未定义的行为(可能是程序崩溃到正确执行。这不是你应该回复的内容。)。主要是从编译磁贴中已知的字符串文字大小,它推断出这一点。

正确的是

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

其中min(x,y)返回xy的最小值。

首先检查大小,然后访问该阵列。首先进行大小检查然后索引到数组中。使用for循环可以减少此处的重复代码。我的意思是你在为那些if语句中的不同索引做的任何事情都可以打包到一个块中,这样它就可以用于for循环(索引变量表示每次迭代中改变的值)。 / p>

另请注意,如果您最后使用memcmp,请不要单独检查字符 - 不需要。您可以使用memcmp直接检查它,然后输出结果。