我正在审核一个C ++项目并有效地看到以下内容:
std::vector<SomeType> objects;
//then later
int size = (int)objects.size();
for( int i = 0; i < size; ++i ) {
process( objects[i] );
}
这就是我所看到的。 std::vector::size()
会返回size_t
,其大小可能与int
的大小无关。即使sizeof(int) == sizeof(size_t)
int
已签名且无法保留size_t
的所有可能值。所以上面的代码只能处理一个很长的向量的下半部分并包含一个bug。正确的方法是对size_t
变量和循环索引使用size
。
那说我很好奇作者为什么写这个?
我唯一的猜测是,首先他省略了(int)
强制转换,编译器发出类似Visual C ++ C4018警告的内容:
warning C4018: '<' : signed/unsigned mismatch
所以作者虽然避免编译器警告的最好方法是简单地将size_t
强制转换为int
,从而使编译器闭嘴。
那个C演员还有其他可能的理智吗?
答案 0 :(得分:9)
我想说在C和C ++中压倒性地使用C强制转换只是为了让编译器闭嘴,很少或根本没有努力去理解它告诉你的内容。悲伤,但却是真的。
答案 1 :(得分:9)
不,这可能就是原因。此外,矢量可能永远不会太长以至于存在截断大小的风险(app。开发人员会知道)。
并且...也许在程序的某些部分,他实际上将“大小”与其他类型的int进行比较,因此将大小设置为“size_t”类型会将其固定在一个地方,但在其他地方将其分解。
答案 2 :(得分:4)
明显的答案是使用:
size_t size = objects.size();
for( size_t i = 0; i < size; ++i ) {
process( objects[i] );
}
或迂腐:
typedef std::vector<SomeType>::size_type s_t;
s_t size = objects.size();
for (s_t i=0; i<size; ++i)
process(objects[i]);
OTOH,除非您确定需要自己编写循环,否则通常最好使用算法:
std::foreach(objects.begin(), objects.end(), process);
答案 3 :(得分:-4)
unsigned int size = (int)objects.size();
for( unsigned int i = 0; i < size; ++i ) {
process( objects[i] );
}