【问题标题】:No compiler error when fixed size char array is initialized without enough room for null terminator固定大小的 char 数组在没有足够空间用于空终止符的情况下初始化时没有编译器错误
【发布时间】:2014-01-08 19:04:27
【问题描述】:

假设我有以下 c char 数组:

char okaysize4[5] = "four";   // line 5
char toosmall4[4] = "four";   // line 6
char toosmall3[3] = "four";   // line 7

当我使用 gcc 4.4.7 编译时,出现以下错误:

array.c:7: 警告:字符数组的初始化字符串太长

第 7 行会出现此错误,因为我试图将 5 个字符 ("four" + \0) 填充到 3 元素数组中。 由于 5 元素数组足够大,所以第 5 行也不会出现错误。

但令我惊讶的是,第 6 行没有类似的错误。最终在 toosmall4 中初始化的是一个未终止的字符串,这可能会导致各种麻烦。

我的理解是 c 字符串文字 "four" 应该是五个字符长,由于空终止符。其实sizeof("four")是5。那为什么编译器不会在这里报错呢?

有什么方法可以改变我的声明/定义/初始化,以便在这种情况下标记错误?

【问题讨论】:

    标签: c arrays compiler-errors char initialization


    【解决方案1】:

    这是第 6 行的预期行为,来自 draft C99 standard 部分 6.7.8 初始化 段落 14 说(强调我的):

    字符类型的数组可以由字符串初始化 字面量,可选地用大括号括起来。的连续字符 字符串文字(包括终止空字符 如果有空间或数组大小未知)初始化 数组的元素。

    在 C11 草案标准中,类似措辞的相关部分是 6.7.914 段,以及 C FAQ says:

    因此该数组不是真正的 C 字符串,不能与 strcpy、printf的%s格式等

    正如 Keith Thompson 所指出的,C++ 更为严格,C++ 标准草案中的相关部分如下所述:

    初始化器的个数不得多于数组元素的个数。 [ 例子:

    char cv[4] = "asdf"; // error
    

    格式不正确,因为隐含的尾随 '\0' 没有空格。 ——结束示例]

    【讨论】:

    • 这个特性一直存在于 C 中。
    【解决方案2】:

    这是合法的,toosmall4 不是字符串,而是一个有效的 char 数组(没有终止的空字符)。

    参考:C FAQ

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 2018-08-23
      • 1970-01-01
      • 2021-11-23
      • 2011-02-18
      • 2012-04-22
      相关资源
      最近更新 更多