gcc 零长度数组上的memcmp出现数组边界错误

jgwigjjp  于 2023-02-23  发布在  其他
关注(0)|答案(1)|浏览(174)

有一个main.c文件,其内容为:

#include "memory.h"
#include "stdint.h"

#define MOLECULE_API_DECORATOR
MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0]      = {};

int main(int argc, char *argv[]) {
    uint32_t size = sizeof(MolDefault_ByteOpt);
    const uint8_t *expected = MolDefault_ByteOpt;
    const uint8_t *actual = NULL;
    if (memcmp(actual, expected, size) != 0){
        return 1;
    }
    return 0;
}

然后我用gcc 12.2.1通过gcc -Werror -Wall main.c编译main. c,将得到:

main.c: In function ‘main’:
main.c:8:5: error: offset ‘0’ outside bounds of constant string [-Werror=array-bounds]
    8 | int main(int argc, char *argv[]) {
      |     ^~~~
main.c:6:38: note: ‘MolDefault_ByteOpt’ declared here
    6 | MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0]      = {};
      |                                      ^~~~~~~~~~~~~~~~~~
main.c:10:31: error: offset ‘0’ outside bounds of constant string [-Werror=array-bounds]
   10 |     const uint8_t *expected = MolDefault_ByteOpt;
      |                               ^~~~~~~~~~~~~~~~~~
main.c:6:38: note: ‘MolDefault_ByteOpt’ declared here
    6 | MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0]      = {};
      |                                      ^~~~~~~~~~~~~~~~~~
main.c:8:5: error: offset ‘0’ outside bounds of constant string [-Werror=array-bounds]
    8 | int main(int argc, char *argv[]) {
      |     ^~~~
main.c:6:38: note: ‘MolDefault_ByteOpt’ declared here
    6 | MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0]      = {};
      |                                      ^~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

如何更改代码以避免此错误?
我希望比较actualexpected,并且编译此代码时不会出现任何警告或错误。

xiozqbni

xiozqbni1#

C 2018 6.2.5 20说(粗体添加):

  • ... * 一个数组 * 类型描述了一个连续分配的非空对象集合,该集合具有一个特定的成员对象类型,称为 * 元素类型 *...

而C 2018 www.example.com 1说,如果数组声明符的[]内部的表达式:6.7.6.2 1 says, if the expression inside [ and ] of an array declarator:

  • ...如果表达式是常量表达式,则其值应大于零...

由于声明符MolDefault_ByteOpt[0]不符合这些规则,因此C标准没有定义该行为。
C 2018 7.1.4 1规定:

  • ...如果一个函数的参数有一个无效值(例如一个函数定义域之外的值,或者一个程序地址空间之外的指针,或者一个空指针,或者当相应的参数不是常量限定的时,一个指向不可修改存储的指针)或者一个类型(在默认参数提升之后)不是一个具有可变参数数量的函数所期望的,则该行为是未定义的...

由于在计算memcmp(actual, expected, size)actual是空指针,因此参数具有无效值,并且C标准未定义该行为。
如何更改代码以避免此错误?
将数组大小设为正数,并传递一个指向memcmp的有效指针(可以传递任何const或未限定对象的地址)。

相关问题