0

考虑

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

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

&data[3]==&data_end

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

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

4

3 回答 3

4

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

5.10 等式运算符[expr.eq]

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

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

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

3.9.2 注意事项:

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

因此,新标准允许符合要求的实现在您的比较中可能会产生正确的结果;仍然没有任何保证。

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

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

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

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

但是,后一种选择需要您的编译器支持constexpr关键字与前一种完全等效。

于 2015-01-03T11:17:43.223 回答
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)];

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

于 2015-01-03T11:16:09.487 回答
0

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

for (/* const */ Foo& foo : data) {
    // stuff with foo.
}
于 2015-01-03T11:52:17.633 回答