简体   繁体   English

初始化固定大小的char数组而没有足够的空终止符空间时,没有编译器错误

[英]No compiler error when fixed size char array is initialized without enough room for null terminator

Suppose I have the following c char arrays: 假设我有以下c char数组:

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

When I compile with gcc 4.4.7, I get the following error: 使用gcc 4.4.7编译时,出现以下错误:

array.c:7: warning: initializer-string for array of chars is too long array.c:7:警告:字符数组的初始化字符串太长

This error is expected for line 7, as I am trying to stuff 5 chars ("four" + \\0) into a 3 element array. 第7行会出现此错误,因为我正在尝试将5个字符("four" + \\0)填充到3个元素的数组中。 Also no error is expected for line 5 as the 5 element array is big enough. 由于5元素数组足够大,因此第5行也不会出现错误。

However I'm surprised there is no similar error for line 6. What ends up getting initialized in toosmall4 is an unterminated string, which can cause all sorts of trouble. 但是,令我惊讶的是,第6行没有类似的错误。最终在toosmall4初始化的是一个未toosmall4的字符串,这可能会引起各种麻烦。

My understanding is that the c string literal "four" should be five characters long, due to the null terminator. 我的理解是,由于空终止符,C字符串文字"four"应为五个字符长。 In fact sizeof("four") is 5. So why does the compiler not give an error here? 实际上sizeof("four")是5。那么为什么编译器在这里没有给出错误?

Is there some way I can alter my declaration/definition/initialization so that an error is flagged in this case? 有什么方法可以更改声明/定义/初始化,以便在这种情况下标记错误?

This is expected behavior for line 6, from the draft C99 standard section 6.7.8 Initialization paragraph 14 says ( emphasis mine ): 这是C99标准草案6.7.8节“ 初始化”14段所述的6.7.8行的预期行为( 强调我的 ):

An array of character type may be initialized by a character string literal, optionally enclosed in braces. 字符类型的数组可以由字符串文字初始化,并可选地用大括号括起来。 Successive characters of the character string literal ( including the terminating null character if there is room or if the array is of unknown size ) initialize the elements of the array. 字符串文字的连续字符( 如果有空间或数组大小未知,则包括终止空字符 )将初始化数组的元素。

In the C11 draft standard the relevant section with similar wording is 6.7.9 paragraph 14 , and as the C FAQ says : 在C11标准草案中,措辞相似的相关部分为6.7.914段,正如C FAQ所述

The array is therefore not a true C string and cannot be used with strcpy, printf's %s format, etc. 因此,该数组不是真正的C字符串,不能与strcpy,printf的%s格式等一起使用。

As Keith Thompson noted, C++ is stricter, the relevant section in the draft C++ standard says the following: 正如Keith Thompson指出的那样, C ++更加严格,C ++标准草案中的相关部分指出:

There shall not be more initializers than there are array elements. 初始化器的数量不得超过数组元素的数量。 [ Example: [示例:

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

is ill-formed since there is no space for the implied trailing '\\0'. 格式错误,因为隐含的尾随'\\ 0'没有空格。 —end example ] —结束示例]

It's legal, toosmall4 is not a string, but a valid char array(without the terminating null character). 合法, toosmall4不是字符串,而是有效的char数组(不包含终止null字符)。

Reference: C FAQ . 参考: C FAQ

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

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