考虑
Foo data[]={{...},{...},{...}};
Foo data_end={...};
如果在数组后面定义了结束标记,则保证
&data[3]==&data_end
我不想手动计算数据中的元素数量。
在没有任何优化选项的情况下,它恰好在gdb中看起来很好,但在使用之前我需要知道编译器无法移动data_end
。如果可以,我该怎么办呢。
答案 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
,则为 cvT*
类型的指针,其值为地址{{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.
}