此功能的返回值是否由C标准定义?
int foo()
{
char buff[128];
// This is the important line:
if ((void*)buff == (void*)(&buff))
return 1;
else
return 0;
}
foo
的结果是什么?在gcc
和clang
上,它始终为1
,,但我不认为这是由标准保证的。
答案 0 :(得分:6)
他们[
buff
和&buff
]保证具有相同的值,还是gcc和clang恰好发生的事情?我问,因为我不认为& buff是“数组开头的地址”,而是变量buff的地址。
他们 保证是相同的值。在C数组中,它们可以被认为是“特殊的”,因为它们不是指针,并且它们被处理的唯一时间是它们被传递给函数并且它们衰减指针。
出于这个原因:
buff == &buff && buff == &buff[0]
但是buff
和&buff
有两种不同的类型,其中&buff
是指向数组的指针(它们仍然指向相同的位置!)。您可以在两者上使用sizeof
来自己查看这些差异。
指针的不相同,正如您所说,它将返回该实际指针变量的地址。数组也不是指向自身的指针,因为为了使指针指向自身,该指针的地址需要存储在该指针变量中。
数组名称只是编译器使用的标签,对应于连续的内存块。它有特殊的属性,上面就是其中之一。
答案 1 :(得分:3)
它将始终返回1.
数组是连续分配的具有元素类型的非空对象集 - 不允许数组在元素之前或之间具有填充。因此,指向数组的指针指向与指向第一个元素的指针相同的位置,尽管它具有不同的类型。
&buff
变量buff
的地址。在这种情况下,变量buff
是一个数组,因此&buff
是数组的地址 - 就像struct
变量的地址与第一个地址的地址相同成员(虽然是不同的类型),数组变量的地址与其第一个成员的地址位置相同。
§6.5.9告诉我们:
6当且仅当两者都是空指针时,两个指针比较相等, 两者都是指向同一对象的指针(包括指向对象的指针) 和一个开头的子对象)......
在这种情况下,“指向对象的指针”是指向数组的指针,“指向子对象开头的指针”是指向该对象的指针。数组的第一个元素。
换句话说,它返回1的原因与此代码相同:
int foo()
{
struct { int a; int b; } s;
return (void*)&s == (void*)&s.a;
}
答案 2 :(得分:2)
是:指向数组的指针衰减为指向第一个元素的指针;所以&buff[0] == &buff
。在你的情况下还有另一件事:当用作函数参数(例如memcpy(buff,...))时,数组 name 会衰减为指针。
对于sizeof buff
,buff 不会衰减成指针。 (提示:使用short或long long来测试,或者使用sizeof(void *)!= sizeof(int)的平台。)