繁体   English   中英

将包含 32 位值的 uint64_t 传递给参数实际上是 uint32_t 的外部 function 是否安全?

[英]Is it safe to pass a uint64_t containing a 32-bit value to an external function whose parameter is actually a uint32_t?

我正在开发一个跨平台程序,该程序从具有 C 链接的动态库调用 function。 我需要支持此动态库的多个版本,但在我需要支持的两个版本之间,有一个 function 参数已从uint32_t更改为uint64_t

如果我将此 function 传递给一个uint64_t ,其中包含的值仍可表示为 uint32_t,那么即使函数的参数实际上是uint32_t ,这样做是否安全?

更具体地说:

如果编译成动态库的function源是:

extern "C" void foo(uint32_t param) {
    ...
}

像这样使用 function 对我来说安全吗:

extern "C" void foo(uint64_t);

uint32_t value32 = 10; // Ensure value can be represented by uint32_t
uint64_t value64 = value32;
foo(value64);

如果是,跨不同平台执行此操作是否安全? 我的这个程序支持 32 位和 64 位 Windows(均编译为 x86)、x86_64 macOS、arm64 macOS、x86 Linux 和 x86_64 Linux。

不,这是非法的。 C++20 [basic.link] p11:

在所有类型调整之后(在此期间 typedef (9.2.3) 被它们的定义替换),引用给定变量或 function 的所有声明指定的类型应相同。

此外,它实际上会在使用通常的基于堆栈的调用约定的 32 位 x86 系统上失败。 uint32_t定义的 function 将在堆栈上寻找一个双字,但两个双字将被压入。 它上面的任何 arguments 都将位于错误的位置。 stdcall 约定更糟,其中被调用的 function 弹出它自己的 arguments; 它会弹出错误的数量,使堆栈不平衡,并在返回后造成各种混乱。

我敢肯定有人会 pipe 与一些人为的系统示例一起工作,但在英特尔系统上请记住,较大的寄存器构建在较小的寄存器之上( rax构建在eax之上,它构建在ax和之上al ),所以你尝试做的事情会起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM