全局变量的内存布局

Memory layout of globals

本文关键字:布局 内存 全局变量      更新时间:2023-10-16

>考虑

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

如果结束标记是在数组之后定义的,是否可以保证

&data[3]==&data_end

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

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

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

5.10 相等运算符[expr.eq]

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

在 C++11 中,它稍微复杂一些:

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

3.9.2 注意事项:

。如果一个 T 类型的对象位于地址A,则 cv T* 类型的指针的值是地址A被称为指向该对象,而不管该值是如何获得的。[注意:例如,超过数组末尾的地址(5.7)将被视为指向数组元素类型的不相关对象,该对象可能位于该地址。

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

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

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

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

template<class T, std::size_t N>
constexpr std::size_t countof(T (&)[N])
{
    return N;
}

但是,后一个选项需要编译器支持 constexpr 关键字才能与前者完全等效。

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

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

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

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

不,它不可靠,在 C++11 中,只需执行

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