2015-01-03 49 views
0

考虑内存布局

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

如果结束标记在阵列之后所定义,是它保证

&data[3]==&data_end 

我不想具有计数在数据元素的数量手动。

它恰好在gdb中没有任何优化选项,但在使用它之前,我需要知道编译器不能移动data_end。如果可以,我该怎么做。

+0

仅通过元件的数量划分的大小或添加恒定,并把它在[] – paulm

回答

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)]; 

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

+0

在这种情况下,这将会占用更少的空间,因为'sizeof(Foo)== 3 * sizeof(void *)' – user877329

+0

@ user877329这取决于Foo的定义什么没有在问题中显示。更值得注意的是,你可以放弃虚拟变量,只要你想要的地址。 – harper

4

您不仅要求什么是不能保证的,但此外,C++ 03兼容的实现必须确保&data[3] != &data_end

5.10平等运营商[expr.eq]

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

在C++ 11,它是一个小更复杂:

相同类型的

两个指针比较相等当且仅当它们都为null,都指向相同的功能,或两者代表相同的地址(3.9.2)。

3.9.2注意事项:

...如果T类型的对象位于一个地址A,类型的指针CVT*其值地址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关键字与前者完全等效。

+0

我低估了你,因为你提出了这个宏,因为它是一个可行的选项。 – Puppy

+1

@Puppy,其实宏*是一个可行的选择。这可能有两个原因:1.我们中的一些人仍然需要处理不完全符合C++ 11并且不支持'constexpr'关键字的编译器。如果没有'constexpr',你不能执行以下操作:'int a [] = {...}; int b [countof(a)];'2.我们中的一些人编写了希望包含在C和C++编译单元中的头文件。在这种情况下,您可能会注意到,模板根本无法使用。 – ach

+0

OP没有这样的要求。另外,如果他将自己的数组定义为'boost :: array',那么首先就没有问题,因为您可以直接请求大小。他提到没有要求结果是一个不变的表达。简而言之,您发布的蹩脚代码适用于不适用于此的要求。 – Puppy

0

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

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