这个C版本可以避免签名/未签名的比较吗?

时间:2010-04-16 12:00:32

标签: c++ visual-c++ stl casting

我正在审核一个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演员还有其他可能的理智吗?

4 个答案:

答案 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] );
}