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

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

问题描述

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

C 中的字符串文字在内部以空字符终止.所以,上面的代码应该会给出一个编译错误,因为字符串文字 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 仅在 char 数组大小小于字符串文字时发出警告(仍然没有错误!).例如,它警告:

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'

推荐答案

用大于它的字符串字面量初始化 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";

定义''plain''字符数组对象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' };

(第 6.7.9 节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 允许使用大于数组的字符串文字初始化字符数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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