【问题标题】:Initializing an array with NULL pointer with GCC throw error使用 NULL 指针初始化数组并引发 GCC 抛出错误
【发布时间】:2020-09-03 04:32:33
【问题描述】:

我正在使用 GCC 和 IAR 来编译一些 C 代码。

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

uint8_t tab[] = NULL;

此示例代码使用 GCC 引发此错误:错误:无效初始化程序

使用 IAR 编译器可以接受语法

GCC 有什么问题,为什么 IAR 编译器会接受它?

【问题讨论】:

  • 你的数组有多少个元素?
  • 除了NULL是一个指针值之外,语法不正确。 uint8_t tab[] = { 0, 1, 2 }; 将生成一个包含三个元素的数组。
  • 这个想法是有一个零元素的数组,我的意思是这只是通用代码的一部分,其中数组可以采用 0 到 n 元素,但在同样的情况下,数组的大小必须为 0 . 语法被 iar 和 armcc 编译器接受,我只有 gcc 的问题
  • 我会说问题是倒退的,更有趣的是为什么其他编译器甚至允许这样做。
  • The idea is to have an array with zero element, 这是不可能的。数组必须具有正大小。 The syntax is accepted with iar and armcc compiler 这是一个编译器扩展(或者只是未定义的行为),我猜这个数组有 1 个元素。

标签: c gcc iar


【解决方案1】:

如果你查看头文件,你会发现 NULL 实际上是

#define NULL ((void*)0) // a void pointer type data.

然而,当您使用以下语法声明数组时

uint8_t tab[] // This is not basically a pointer | it is an array.

您正在将指针数据类型分配给问题所在的数组数据类型。

【讨论】:

  • IAR 和 armcc 编译器确实接受这种语法并且不会出错。该错误仅在 gcc 中出现。所以我想知道这里有什么区别
  • 每个编译器由不同的组织实现,并针对不同的操作系统和硬件。 gcc、mingw 和 vc++ 编译器以 x86 架构为目标,但它们以不同的方式处理和表示错误,这是唯一的区别。但是为什么这个表达式不起作用的基本概念是上面的答案
  • 旧版编译器使用[] 表示法(两个括号之间没有任何内容,用于声明指针(并且此表示法在参数声明中保留)
【解决方案2】:

你可以用任何正数的元素来初始化数组,但是你不能用NULLint给数组赋值。但是您可以将数组与NULL 指针进行比较。

例如:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

uint8_t tab[] = {}; // it's OK but it does not make sense with 0 element in the array
// uint8_t tab[] = {0}; it's OK size of array  = 1
// uint8_t tab[] = {0,1,2,3}; // it is OK, size of array = 2
int main() {

    if(tab == NULL) { // it's OK, you can compare
        // do sth
    }
    // tab = NULL it's not accepted
    // tab = 0x1010101 it's not accepted also

    printf("%lu\n", sizeof(tab)); // it will print 0
    return 0;
}

您还可以将动态数组与size = 0 一起使用:

uint8_t *tab2;
...
tab2 = malloc(0);
// do something
tab2 = realloc(tab2, 3); // re-allocate the pointer for lager size

【讨论】:

  • 这将被 gcc uint8_t tab[] = {} 接受;但不是 iar,我需要为 iar 和 gcc 编译它的代码,所以这是我的噩梦
  • 您问的是关于 GCC 而不是 IAR 的问题。但是如果你仍然想要size = 0,你可以使用动态分配。试试:uint8_t *tab = malloc(0); 然后你想调整大小可以使用tab = realloc(tab, another size);
  • 哦,伙计,您不必执行malloc(0),您只需分配NULL,然后分配realloc(NULL, new size)(您会得到一个有效的指针)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 2019-03-27
  • 2019-08-19
相关资源
最近更新 更多