c ++

时间:2017-10-06 06:59:48

标签: c++

c ++中不允许指向整数文字的指针。 但是,我可以使用address-of(&)运算符来获取文字的地址。

const int & a = 5;
const int & b = 5;
cout << &a << endl;
cout << &b << endl;

结果是&amp; a和&amp; b不同!!! 为什么???在字符串文字的情况下,一个字符串文字只有一个内存地址。为什么同一个整数文字在再次声明时会有不同的内存地址?

3 个答案:

答案 0 :(得分:4)

你没有获取文字的地址:'5'是一个prvalue,用于初始化int的临时类型,其生命周期绑定到const引用a。所以ansible-playbook必须(*)保持为真,据我所知:

  

除非对象是零字段或零大小的基类子对象,否则该对象的地址是它占用的第一个字节的地址。如果一个是另一个的子对象,或者如果至少一个是零大小的基类子对象并且它们具有不同类型,则两个不是位字段的对象可以具有相同的地址;否则,他们将拥有不同的地址 ^ 4。 4 [(*) 在“as-if”规则下,允许实现在同一机器地址存储两个对象或不存储   如果程序无法观察差异]

,则该对象完全没有

此外,作为的演示,如规则,程序

&a!=&b

编译为(gcc 7.2 -O3):

int main(){
  const int a = 5;
  const int b = 5;
  return &b!=&a;
}

:)

答案 1 :(得分:0)

如果右值被引用,则不再是右值。参考一个右值使它被存储就好像它是一个左值。

例如

    while (!find || open.Count > 0)
    {
        Vector2 current = LowestF(Start, open, Destination);

        if (current == Destination)
        {
            find = true;
            break;
        }

        close.Add(current);
        open.Remove(current);

        List<Vector2> adjacent = MoveDirection(current);

        lowF = int.MaxValue;

        for (int i = 0; i < adjacent.Count; i++)
        {
            if (close.Contains(adjacent[i]))
                continue;

            if(getF(Start, adjacent[i], Destination) < lowF)
            {
                lowF = getF(Start, adjacent[i], Destination);
                lowV = adjacent[i];
            }

            if (!open.Contains(adjacent[i]))
            {
                open.Add(adjacent[i]);
            }

            yield return new WaitForSeconds(0.0125f);
        }
    }

所以你肯定可以拿一个左值的地址。

答案 2 :(得分:0)

两个文字确实具有相同的地址,该地址是 no-address 。除字符串文字外,文字没有地址。

在您的代码中,您获取文字的地址,这根本不可能。 address-of运算符需要左值,而文字不是一个!因此,如果您确实尝试使用int* a = &5;中的文字地址,编译器就不会让您。

您正在创建对rvalue(实际为prvalue)的const引用。现在,如果您尝试在没有const关键字的情况下进行编译,并想知道为什么不起作用,那也是出于同样的原因。如果没有constness,则需要左值来绑定引用,而文字不是一个。

注5.1.1:

  

文字[expr.prim.literal]   文字是主要表达方式。它的类型取决于它的形式(2.13)。字符串文字是左值;所有其他文字都是prvalues。

这就解释了为什么它对字符串文字“起作用”,它们是左值。您可以获取左值的地址。它还解释了为什么它不适用于整数文字。

但请注意,取两个相同的字符串文字的地址不一定会产生相同的地址。你错了。

在优化版本中,或在明确请求时,许多编译器将执行string pooling。非常非常严格地说,从逻辑的角度看这是不正确的(因为两个字符串文字,无论是否相同,两个不同的对象,除了位域和嵌套对象,不同的对象预计会有不同的地址),但令人惊讶的是,该标准确实允许实施完全合法地摆脱这种情况。

C ++ 98和C ++ 03中的2.13.4 / 2,C ++ 11中的2.14.12 / 11,C ++ 14中的2.14.5 / 12:

  

是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的

每个2.13.5 / 16 in C ++ 17:

  

[...]是否所有字符串文字都是不同的(即存储在非重叠对象中)以及字符串文字的连续评估是否产生相同或不同的对象未指定

因此,在C ++ 17之前的版本中,编译器(“实现”)可能会选择执行池化,但在“实现定义”的约束下,这意味着特定的编译器必须遵循任何它选择了,发生的事情必须是可证实的(记录在案)。

在C ++ 17中,标准仅表明它未指定。这基本上意味着......“无论如何”。

因此,编译器可以进行字符串池化(合法地),但 的一般假设是错误的。