【问题标题】:Could this C cast to avoid a signed/unsigned comparison make any sense?这个 C 强制转换以避免有符号/无符号比较是否有意义?
【发布时间】:2010-04-16 12:00:31
【问题描述】:

我正在审查一个 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 的所有可能值。所以上面的代码只能处理一个很长的向量的下半部分,并且包含一个错误。正确的方法是将size_t 用于size 变量和循环索引。

也就是说我很好奇作者为什么会写这个?

我唯一的猜测是,首先他省略了 (int) 演员表,编译器发出了类似 Visual C++ C4018 警告:

warning C4018: '<' : signed/unsigned mismatch

所以作者认为避免编译器警告的最佳方法是简单地将 size_t 转换为 int 从而使编译器关闭。

C 演员阵容还有其他可能的合理原因吗?

【问题讨论】:

  • Nitpick: size() 返回实现定义的vector::size_type,不一定是size_t
  • 挑剔的挑剔:默认分配器确实使用size_t作为size_type。是的,你可以写vector&lt;int&gt;::size_type s = v.size();,但是当你更改v 的分配器时,你仍然会使用错误的size_type,并且需要查找和更改用法(但同样,typedefs 可以提供帮助)。跨度>
  • 只要你 typedef 你的向量类型,使用 YourVectorTypedef::size_type 应该总是返回正确的类型。
  • nitpick 的 nitpick 的 nitpick:只有 std::string 使用 allocator::size_type 作为其 size_typestd::vector 改用“实现定义的无符号整数类型”。
  • @UncleBens ^^(挑剔通知器)

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


【解决方案1】:

不,这可能是原因。再加上向量可能永远不会太长以至于有截断大小的风险(应用程序开发人员会知道这一点)。

而且...也许在程序的某些部分,他实际上将“size”与其他 int 类型的东西进行了比较,因此将 size 设为“size_t”类型会在一个地方修复它,但在其他地方破坏它。

【讨论】:

    【解决方案2】:

    我想说的是,在 C 和 C++ 中大量使用 C 类型转换只是为了让编译器闭嘴,而很少或根本不努力试图理解它在告诉你什么。悲伤,但真实。

    【讨论】:

    • 很多错误都是微不足道的,在上下文中没有意义,或者不可读。有道理,很多人的反应都是“闭嘴”。
    • @Jay 这不是真的。大多数错误都是有意义的,并且应用强制转换几乎总是错误的处理方式。我自己的座右铭是——“如果需要演员,那就错了”。
    【解决方案3】:

    显而易见的答案是使用:

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

    【讨论】:

    • 在第一个版本中,您再次转换为 int。
    • @Sharptooth:哎呀——我复制了他的代码并打算修复它,但错过了。感谢您指出。
    【解决方案4】:
    unsigned int size = (int)objects.size();
    for( unsigned int i = 0; i < size; ++i ) {
        process( objects[i] );
    }
    

    【讨论】:

    • 什么?为什么不直接使用size_t?为什么还要投到int
    • 什么?这更糟。 size 变量的预期类型是 size_t,去 unsigned int 有什么意义?
    • size_t 可能大于 unsigned int
    猜你喜欢
    • 2015-08-28
    • 1970-01-01
    • 2011-05-03
    • 2011-07-21
    • 2017-07-27
    • 2022-11-29
    • 2016-08-07
    • 1970-01-01
    相关资源
    最近更新 更多