c - 64 位上的 int 与 size_t

标签 c portability 32bit-64bit

将代码从 32 位移植到 64 位。很多地方都有

int len = strlen(pstr);

现在这些都会生成警告,因为 strlen() 返回 64 位的 size_t 而 int 仍然是 32 位。所以我一直在用

替换它们
size_t len = strlen(pstr);

但我刚刚意识到这并不安全,因为 size_t 是无符号的,它可以被代码视为已签名(我实际上遇到了一个导致问题的情况,谢谢,单元测试!)。

盲目地将 strlen return 转换为 (int) 感觉很脏。或者也许它不应该?
所以问题是:是否有一个优雅的解决方案?我的代码库中可能有一千行这样的代码;我无法手动检查它们中的每一个,测试覆盖率目前介于 0.01 和 0.001% 之间。

最佳答案

前段时间我在我的博客上发布了一篇关于此类问题的简短说明,简短的回答是:

Always use proper C++ integer types

长答案: 在 C++ 中编程时,最好使用与特定上下文相关的适当整数类型。一点点严格总是有返回的。忽略定义为特定于标准容器的整数类型的趋势并不少见,即 size_type。它可用于许多标准容器,如 std::string 或 std::vector。这种无知很容易报复。

下面是一个错误使用类型来捕获 std::string::find 函数结果的简单示例。我很确定很多人会认为这里的 unsigned int 没有问题。但是,实际上这只是一个错误。我在 64 位架构上运行 Linux,当我按原样编译这个程序时,它按预期工作。但是,当我替换 1 行中的字符串时使用 abc,它仍然有效,但不如预期:-)

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s = "a:b:c"; // "abc" [1]
  char delim = ':';
  unsigned int pos = s.find(delim);
  if(string::npos != pos)
  {
    cout << delim << " found in " << s << endl;
  }
}

修复非常简单。只需将 unsigned int 替换为 std::string::size_type。如果编写此程序的人注意使用正确的类型,则可以避免该问题。更不用说该程序可以立即移植。

我见过很多次此类问题,尤其是在前 C 程序员编写的代码中,他们不喜欢戴上 C++ 类型系统强制执行和要求的严格性。上面的例子是一个微不足道的例子,但我相信它很好地表达了问题的根源。

我推荐精彩文章64-bit development由 Andrey Karpov 撰写,您可以在其中找到有关该主题的更多信息。

关于c - 64 位上的 int 与 size_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2519452/

相关文章:

linux - Linux 上的可移植 JRE - 可能吗?

c++ - 如何在 64 位 DLL 中查找导出函数的地址?

delphi - WParam 的 "low word"和 "high word"位置在 64 位代码中是否发生变化?

C++ 17 std::filesystem 无法在其他(Windows 10)计算机上运行

php - PHP 中大字符串的按位运算

将列表连接成列表并在c中打印列表的列表(链表的链表)

c++ - 字符集中字符的顺序

c - 在 C 中以编程方式使用 CMD

c - 如何从C程序向Linux命令发送命令

java - 假设 - 支持非字符串文本中的非 ASCII 字符