全局变量的内存布局

时间:2015-01-03 10:54:49

标签: c++ memory-layout

考虑

Foo data[]={{...},{...},{...}};
Foo data_end={...};

如果在数组后面定义了结束标记,则保证

&data[3]==&data_end

我不想手动计算数据中的元素数量。

在没有任何优化选项的情况下,它恰好在gdb中看起来很好,但在使用之前我需要知道编译器无法移动data_end。如果可以,我该怎么办呢。

3 个答案:

答案 0 :(得分:4)

不仅保证您要求的内容,而且符合C ++ 03的实现必须确保&data[3] != &data_end

  

5.10 Equality operators [expr.eq]

     

1 ...同一类型的两个指针比较相等,当且仅当它们都为空时,都指向同一个对象或函数,或者两个指针都指向同一个数组的末尾。

在C ++ 11中,它有点复杂:

  

同一类型的两个指针比较相等,当且仅当它们都为空时,都指向相同的函数,或者两者都表示相同的地址(3.9.2)。

3.9.2注意事项:

  

...如果T类型的对象位于地址A,则为 cv T*类型的指针,其值为地址{{1据说指向该对象,无论如何获得该值。 [注意:例如,超过数组末尾的地址(5.7)将被视为指向可能位于该地址的数组元素类型的无关对象。 ...... - 注意事项]

因此,新标准允许符合条件的实现可能在您的比较中产生真实;仍然没有保证。

如果需要计算数组的元素数,请使用以下stock micro:

A

或者,如果您不喜欢宏,请使用以下功能:

#define countof(ARR) (sizeof (ARR) / sizeof *(ARR))

然而,后一个选项需要您的编译器支持template<class T, std::size_t N> constexpr std::size_t countof(T (&)[N]) { return N; } 关键字与前者完全相同。

答案 1 :(得分:1)

没有。编译器以任何顺序或任何对齐方式放置变量并不是一个可靠的假设。对齐变量之间可能存在差距,我已经看到了按字母顺序排序变量的编译器。

如果你想知道指向数组中元素的指针,你需要知道数组元素的数量。

#define _dimof(a) (sizeof(a)/sizeof(a[0]))
Foo data[] = ... ;
// The type of the variable has been changed.
Foo* data_end = &data[_dimof(data)];

您可以删除此段落,因为它已被添加以修复代码中的语法错误。

答案 2 :(得分:0)

不,它不可靠,在C ++ 11中,只是做

for (/* const */ Foo& foo : data) {
    // stuff with foo.
}