在确定数组的大小时,括号会有所不同吗? [英] Do parentheses make a difference when determining the size of an array?

查看:70
本文介绍了在确定数组的大小时,括号会有所不同吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下程序在 gcc 4.8.2 上两次打印相同的数字:

#include int main(){字符 [13];printf("sizeof a 是 %zu\n", sizeof a );printf("sizeof(a) 是 %zu\n", sizeof(a));}

根据这篇 reddit 帖子,gcc 在这方面不符合标准,因为当数组到指针衰减不发生时,括号表达式不在例外列表中.

这家伙说得对吗?这是相关的标准报价:

<块引用>

除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是用于初始化字符类型数组的字符串文字,或是用于初始化元素类型与 wchar_t 兼容的数组的宽字符串文字,具有类型类型数组"的左值被转换为具有类型指向类型的指针"的表达式,该表达式指向数组对象的初始成员,不是左值.

为了清楚起见,他认为 (a) 应该触发数组到指针的衰减,因为上面的列表中没有包括括号(sizeof 运算符,一元 & 运算符,字符串文字作为初始值设定项).

解决方案

看似多余的括号是否会影响程序的语义是 C 标准中的一个长期存在的问题,仍未得到充分解决.

通常声称 ((void*)0) 在技术上不是空指针常量,因为没有规则说带括号的空指针常量是空指针常量.>

一些编译器为 char s[] = ("abc"); 发出错误,因为虽然可以从字符串文字初始化字符数组,但该规则不包括括号字符串文字.

类似的例子还有很多.您已找到其中之一.

据我所知,共识基本上是规则应该是 C++ 所做的,但 C 从未正式采用的规则.C++ 使带括号的表达式在功能上等同于不带括号的表达式,但有一些明确说明的例外.这将一次涵盖所有这些问题.

所以从技术上讲,这个人可以被认为是正确的,但这是对标准的过于严格的解释,没有人真正遵循,因为众所周知,标准在这里只是有问题.

The following program prints the same number twice on gcc 4.8.2:

#include <stdio.h>

int main()
{
    char a[13];
    printf("sizeof a  is %zu\n", sizeof a );
    printf("sizeof(a) is %zu\n", sizeof(a));
}

According to this reddit post, gcc is not standard-conformant in this respect, because a parenthesized expression is not on the list of exceptions for when array-to-pointer decay does not happen.

Is this guy correct? Here is the relevant standard quote:

Except when it is the operand of the sizeof operator or the unary & operator, or is a character string literal used to initialize an array of character type, or is a wide string literal used to initialize an array with element type compatible with wchar_t, an lvalue that has type 'array of type' is converted to an expression that has type 'pointer to type' that points to the initial member of the array object and is not an lvalue.

Just to be clear, he argues that (a) should trigger array-to-pointer decay, because parentheses are not covered in the list above (sizeof operator, unary & operator, string literal as initializer).

解决方案

Whether seemingly redundant parentheses affect the semantics of a program is a long-standing issue in the C standard that still hasn't been adequately resolved.

It is commonly claimed that ((void*)0) is technically not a null pointer constant, because there is no rule that says a parenthesised null pointer constant is a null pointer constant.

Some compilers issue an error for char s[] = ("abc");, because while a character array can be initialised from a string literal, that rule doesn't cover parenthesised string literals.

There are many similar examples. You've found one of them.

From what I can tell, the concensus is basically that the rule should be what C++ does, but what C never formally adopted. C++ makes a parenthesised expression functionally equivalent to the non-parenthesised expression, with a few explicitly-stated exceptions. This would cover all those issues at once.

So technically, the guy could be considered correct, but it's an overly strict interpretation of the standard that nobody really follows, since it's common knowledge that the standard is simply faulty here.

这篇关于在确定数组的大小时,括号会有所不同吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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