【问题标题】:Passing a temporary struct value to function works on Mac but not Windows将临时结构值传递给函数适用于 Mac 但不适用于 Windows
【发布时间】:2020-03-16 23:10:42
【问题描述】:

我在将游戏从 Mac 移植到 Windows 时遇到了将 SDL_Rects 传递给几个函数的问题。以下是一些伪代码来代表我的问题:

void someFunction(SDL_Rect rect)
{
  // Does something
}

someFunction((SDL_Rect) {0, 0, 10, 10});

每当我执行上述操作时,Visual Studio 都会说这是一个错误。它在 Xcode 中工作得很好,并且似乎不是特定于平台的东西,因为它只是聚合初始化,所以有人可以解释为什么吗?

【问题讨论】:

  • 你把VS设置成C++17了吗?
  • 你没有创建一个临时的SDL_rect,不是真的。您正在创建其他东西(如果我确定我会回答什么)并将其转换为SDL_rectsomeFunction(SDL_Rect {0, 0, 10, 10}); 会做一个临时的。
  • 如果 VS 说这是一个错误,在您的问题中显示该错误会很有帮助。
  • @Ron 在后台可能会更神奇。当我使用 gcc 8.3 -pedantic 为 C++17 编译时,会发出警告 ISO C++ 禁止复合文字,所以我假设我们得到了复合文字。由于 pedantic 说它不是 kosher,所以我得出的结论是它来自 C99,而 MSVS 不支持它。 godbolt.org/z/tFsV4H
  • 你可能想要SDL_Rect{0,0,10,10}

标签: c++ visual-c++ clang


【解决方案1】:

此代码在 ISO C++ 中无效。它在 ISO C 中有效,一些 C++ 编译器可能支持它作为扩展。

在 C++ 中,您可以执行以下任何操作:

  • someFunction( SDL_Rect{0, 0, 10, 10} );
  • someFunction( {0, 0, 10, 10} );

为了在两种语言中都有效(不是有任何理由这样做),我认为您需要为参数使用命名变量:

SDL_Rect foo = { 0, 0, 10, 10 };
someFunction(foo);

或者可能是根据语言进行不同扩展的预处理器宏。

【讨论】:

  • (SDL_Rect) {0, 0, 10, 10} 和 (SDL_Rect {0, 0, 10, 10}) 有什么区别。他们不是都在选角吗?
  • @K.S.Bilodeau 不,第一个是语法错误。在 C 风格的强制转换中,带括号的类型名后面必须跟一个表达式,而花括号列表不是表达式
【解决方案2】:

对于那些碰巧遇到和我一样的问题的人来说,问题是 gcc 有一个扩展,它允许一种叫做复合文字的东西。这是一篇关于它的文章:Compound Literals Extension GCC。修复它的最简单方法是正常投射,如上面的答案所示!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多