【问题标题】:va_arg begins by the second parameter on mac (clang++)va_arg 以 mac 上的第二个参数开头(clang++)
【发布时间】:2021-03-04 14:53:44
【问题描述】:

代码

TextureMeta(string tex_, int args_, const char* ...)
{
    va_list vl;
    va_start(vl, args_);
    for (int i = 0; i < args_; i++)
    {
        string img_(va_arg(vl, char*));
        cout << img_ << endl;
        images.push_back(img_);
    }
    va_end(vl);
}

在 MSVC 上它工作正常,但在 MacOS 上生成的应用程序出现分段错误, 我可以看到代码首先打印第二个参数,日志显示TextureMeta(this=0x000000010174d680, tex_="resource/skybox/mitsuumi", args_=6, (null)="resource/skybox/mitsuumi/right.jpg"),似乎第一个 va 参数成为函数参数并且无法迭代。 我使用 CMake,生成器是默认的。

这是一个 mac clang 错误吗? 或者上面的代码中是否有一些未定义的标准?

【问题讨论】:

  • 有什么理由使用 C 省略号,而不是 std::initializer_list&lt;const char*&gt;
  • 这是一个 mac clang 错误吗? -- 建议 -- 总是假设是你的代码有问题,而不是编译器。
  • @AyxanHaqverdili -- 是的。另外,如果上面的代码真的是编译器的错误,全世界成千上万的程序员都会注意到并报告它。 OP 应该意识到 C++ 编译器是最受压力测试的工具之一。跳转到“它是编译器错误吗?”因为第一反应不是一个好习惯。
  • 请注意,“工作正常”是未定义行为的最常见和邪恶的表现形式。

标签: c++ macos parameters arguments clang


【解决方案1】:
TextureMeta(string tex_, int args_, const char* ...)

这是的缩写

TextureMeta(string tex_, int args_, const char*,  ...)

这意味着您在椭圆之前有 3 个常规参数。你想要的是:

TextureMeta(string tex_, int args_, ...)

Live

【讨论】:

  • 为什么const char* ... 的语法有效?
  • 回答了我自己的问题:cppreference - "要声明可变参数函数,省略号会出现在参数列表之后,例如int printf(const char* format...);,前面可能有一个可选的逗号”。它通常只是在命名参数之后,所以看到const char* ... 看起来很奇怪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 2018-11-17
  • 2019-05-15
  • 2018-03-22
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多