C指向数组明确定义的行为

时间:2011-12-07 22:08:23

标签: c

此功能的返回值是否由C标准定义

int foo()
{
    char buff[128];
    // This is the important line:
    if ((void*)buff == (void*)(&buff))
        return 1;
    else
        return 0;
}

foo的结果是什么?在gccclang上,它始终为1,但我不认为这是由标准保证的。

3 个答案:

答案 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)的平台。)