【问题标题】:How to avoid problems with size_t and int types in 64bit C++ builds?如何避免 64 位 C++ 版本中 size_t 和 int 类型的问题?
【发布时间】:2010-09-30 17:42:00
【问题描述】:

今天我第一次构建了我的项目的 64 位版本。基本上它编译、链接和运行正常,除了抱怨新的 64 位 size_t 类型和简单的 int 类型之间不兼容的警告。这主要发生在我的代码中这样的情况:

void func(std::vector<Something> &vec)
{
    int n = vec.size();
    for (int i=0; i < n; i++)
    {
        ....vec[i]....
    }
}

这很容易解决,我读过一篇文章说应该使用 size_t 或 ptrdif_t 作为循环索引。但是在这种情况下我该怎么办?

void outsideLibraryFunc(int n);

void func(std::vector<Something> &vec)
{
    int n = vec.size();
    outsideLibraryFunc(n);
}

我无法更改外部库的函数声明,它需要一个 int 类型的参数,我需要将向量元素的数量传递给它。除了禁用编译器警告,我还能做什么?

【问题讨论】:

  • +1 问:我不知道 size_t != unsigned int
  • @pm100 它可以是,在大多数 32 位系统上它是,但它不是必须的。特别是,在使用 LP64 或 LLP64 约定的 64 位系统(大多数现代 64 位系统)中,它往往大于 unsigned int
  • ssize_t 有时可用于有符号的 size_t

标签: c++ 64-bit size-t


【解决方案1】:

int 进行显式转换,例如

void outsideLibraryFunc(int n);

void func(std::vector<Something> &vec)
{
    outsideLibraryFunc(static_cast<int>(vec.size()));
}

它不会消除将size_t 转换为int 的任何潜在问题,但它会告诉编译器您是故意进行转换的,它不会警告您。

【讨论】:

  • +1,更大的优势是,在阅读代码时,您会看到原本隐含的强制转换,并且知道编译器无法拥有,您可以验证它是否有意义。如示例:虽然编译器无法确保 size_t 类型的函数返回的值适合 32 位整数,但您可以手动检查它是否有意义。
【解决方案2】:

投吗?严重的是,如果您无法更改外部库,那么您无能为力。为了更加安全地检查溢出。

【讨论】:

  • +1 用于溢出检查(尽管您很少有超过 20 亿个对象)
  • 如何检查溢出?我确实记得 EFLAGS 中的溢出位,但是如何以 C 方式访问它?
  • @neuviemeporte: if (vec.size() > INT_MAX) { /* error /} else { / (int) cast will work */ }。但就像维克托说的那样,检查可能有点矫枉过正......
  • 是的,溢出检查几乎肯定是矫枉过正。只是缩小演员阵容需要考虑的事情。操作后检查 CPU 的标志是不可移植的。就像迈克尔写道:只需找到或定义平台的最大整数,比较。但实际上,如果你有一个包含这么多项目的向量,它会溢出一个 int,你可能不会有任何剩余的内存,也不必担心这些事情。
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 2021-09-14
  • 2010-11-02
相关资源
最近更新 更多