为什么gcc允许char数组初始化时使用比数组大的字符串? [英] Why does gcc allow char array initialization with string literal larger than array?

查看:96
本文介绍了为什么gcc允许char数组初始化时使用比数组大的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

int main()
{
    char a[7] = "Network";
    return 0;
}

C中的字符串文字在内部以 nul字符终止.因此,上面的代码应该给出编译错误,因为字符串文字Network的实际长度为8,并且不能放入char[7]数组中.

A string literal in C is terminated internally with a nul character. So, the above code should give a compilation error since the actual length of the string literal Network is 8 and it cannot fit in a char[7] array.

但是,Ubuntu上的 gcc (即使使用-Wall)也可以编译此代码而不会出现任何错误或警告. 为什么gcc允许这样做而不将其标记为编译错误?

However, gcc (even with -Wall) on Ubuntu compiles this code without any error or warning. Why does gcc allow this and not flag it as compilation error?

gcc仅给出警告(仍然没有错误!).例如,它警告:

gcc only gives a warning (still no error!) when the char array size is smaller than the string literal. For example, it warns on:

char a[6] = "Network";

[相关] Visual C ++ 2012 给出了char a[7]的编译错误:

[Related] Visual C++ 2012 gives a compilation error for char a[7]:

1>d:\main.cpp(3): error C2117: 'a' : array bounds overflow
1> d:\main.cpp(3) : see declaration of 'a'

推荐答案

使用大于C的字符串文字初始化char数组在C中是可以的,但在C ++中是错误的.这就解释了gcc和VC ++在行为上的区别.

Initializing a char array with a string literal that is larger than it is fine in C, but wrong in C++. That explains the difference in behavior between gcc and VC++.

如果使用VC ++编译与C文件相同的文件,则不会出错.如果使用g ++将其编译为C ++文件,则会出现错误.

You would get no error if you compiled the same as a C file with VC++. And you would get an error if you compiled it as a C++ file with g++.

C标准说:

可以通过字符串初始化字符类型的数组 文字或UTF-8字符串文字,可以选择用大括号括起来. 字符串文字的连续字节(包括终止null 字符(如果有空间或数组大小未知) 初始化数组的元素.

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the 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.

[...]

示例8

声明

char s[] = "abc", t[3] = "abc";

定义元素已初始化的普通"字符数组对象st 与字符串文字. 该声明与

defines ‘‘plain’’ char array objects s and t whose elements are initialized with character string literals. This declaration is identical to

char s[] = { 'a', 'b', 'c', '\0' },
     t[] = { 'a', 'b', 'c' };

( C11标准草案,最终标准中的实际措辞可能有所不同.)

(Section 6.7.9 of the C11 draft standard, actual wording in final standard might be different.)

这意味着,如果数组没有空间,则删除终止符是完全正确的.也许这是出乎意料的,但这恰恰是该语言的工作方式,以及(至少对我而言)众所周知的功能.

This means that it's perfectly correct to drop the termination character if the array doesn't have room for it. It's maybe unexpected, but it's exactly how the language is supposed to work, and a (at least to me) well-known feature.

相反,C ++标准说:

On the contrary, the C++ standard says:

初始化器的数量不得超过数组元素的数量.

There shall not be more initializers than there are array elements.

示例:

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

格式错误,因为隐含的尾随'\ 0'没有空格.

is ill-formed since there is no space for the implied trailing '\0'.

(C ++ 2011草案的8.5.2 n3242 .)

这篇关于为什么gcc允许char数组初始化时使用比数组大的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆