函数调用时自动将结构体转换为指针

发布于 2024-10-18 14:34:22 字数 698 浏览 1 评论 0原文

我们的项目中有一个看起来非常正常的 printf 样式函数,经过修改,%g 格式意味着打印 GUID 而不是普通的浮点类型。对于我们的例子,GUID 看起来像这样:

struct guid {
  uint32_t  Data1;
  uint16_t  Data2;
  uint16_t  Data3;
  uint8_t   Data4[8];
};

实际上,打印函数期望传递一个指向 GUID 的指针,而不是结构本身:

struct guid myGuid = { 0x867FD1E7, 0x9AA7, 0x472A, { 0xAA, 0x56, 0xF2, 0xDA, 0x66, 0x62, 0xCD, 0x4D } };
print("%g", &myGuid);

然而,在源代码库中有几个地方,由于某种原因,整个 guid 都被传递:

print("%g", myGuid);

这种调用风格似乎在 MSVC2003 中工作得很好 - 是否有一些 ABI 要求使编译器将该函数调用风格转换为实际上在幕后传递指针?当将此代码库移植到使用 clang/llvm 时,它肯定不会做同样的事情。

有人可以解释为什么第二个版本的调用适用于 MSVC 吗?如果能提供相应文档的指针,我们将不胜感激!

We have a pretty normal looking printf style function in our project, with the modification that the %g format means to print a GUID instead of the normal floating-point type. For our case, a GUID looks something like this:

struct guid {
  uint32_t  Data1;
  uint16_t  Data2;
  uint16_t  Data3;
  uint8_t   Data4[8];
};

In reality, the print function expects a pointer to the GUID to be passed, as opposed to the structure itself:

struct guid myGuid = { 0x867FD1E7, 0x9AA7, 0x472A, { 0xAA, 0x56, 0xF2, 0xDA, 0x66, 0x62, 0xCD, 0x4D } };
print("%g", &myGuid);

There are several places in the source base, however, where for some reason the entire guid is passed:

print("%g", myGuid);

This style of call seems to work fine with MSVC2003 - is there some ABI requirement that makes the compiler translate that function call style to actually pass a pointer behind the scenes? When porting this codebase to use clang/llvm, it certainly doesn't do the same thing.

Can somebody explain why the second version of the call works with MSVC? A pointer to the appropriate documentation would be much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哀由 2024-10-25 14:34:22

我想我在 MSDN 上找到了一些说明:

任何不适合 8 个字节的参数,或者不是 1、2、4 或 8 个字节的参数,都必须通过引用传递。

看来是时候修复 clang 了!

I think I found some clarification on MSDN:

Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference.

Looks like it's time to fix clang!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文