【问题标题】:clang error: cannot pass object of non-trivial type 'std::vector<long>' through variadic method; call will abort at runtime [-Wnon-pod-varargs] [duplicate]clang 错误:无法通过可变参数方法传递非平凡类型 \'std::vector<long>\' 的对象;调用将在运行时中止 [-Wnon-pod-varargs] [重复]
【发布时间】:2022-08-03 11:11:43
【问题描述】:

我用gcc构建,编译成功,运行成功! 但是当我用 clang 构建我的 repo 时,我遇到了编译错误!

这是一个错误,其他错误类似

./engine/dispatcher.h:74:57: error: cannot pass object of non-trivial type \'std::vector<long>\' through variadic method; call will abort at runtime [-Wnon-pod-varargs]
  bool ret = (this->runner->*ins_func[func_i][dtype_i])(std::forward<Args>(args)...);

许多函数调用此代码

template <class RunnerType>
template <typename... Args>
bool Dispatcher<RunnerType>::dispatcher(const int func_i, const int dtype_i, Args &&...args) {
bool ret = (this->runner->*ins_func[func_i][dtype_i])(std::forward<Args>(args)...);
}

陈述

template <typename RunnerType>
class Dispatcher {
 public:
bool (RunnerType::*ins_func[INSTRUCTION_NUM][DTYPE_NUM])(...);
}

其他相关代码

template <typename RunnerType>
void Dispatcher<RunnerType>::init_instructions_func() {
  ins_func[privpy::func::SAVE][privpy::dtype::INT8] = reinterpret_cast<bool (RunnerType::*)(...)>(
      &RunnerType::template save<int8_t, typename RunnerType::TypeSet::INUMT8>);
  ins_func[privpy::func::SAVE][privpy::dtype::INT16] = reinterpret_cast<bool (RunnerType::*)(...)>(
      &RunnerType::template save<int16_t, typename RunnerType::TypeSet::INUMT16>);
}

clang-版本:14.0.0
操作系统:ubuntu20.04

我写了一个演示来重现问题,显示同样的错误

#include <iostream>
#include <string>
#include <vector>

using namespace std;

bool (*ins_func)(...);
bool save(int a,vector<long> arr)
{
        cout << a << endl;
        cout <<   \" hello \" << endl;
        return true;
}
template <typename T, typename... Args>
bool sum_super_cool(T v, Args... args) {
        cout << \"pre\" << endl;
        bool ret = (*ins_func)(std::forward<Args>(args)...);
        return ret;
}

int main(int argc, char** argv) {
    ins_func = reinterpret_cast<bool (*)(...)>(&save);
    vector<long> arr;
    arr.push_back(123);
    sum_super_cool(1, 2, arr);

    return 0;
}
root@3e53105276e1:~/test/main# clang++-14 variable_arg.cpp -std=c++17
variable_arg.cpp:17:25: error: cannot pass object of non-trivial type \'std::vector<long>\' through variadic function; call will abort at runtime [-Wnon-pod-varargs]
        bool ret = (*ins_func)(std::forward<Args>(args)...);
                               ^
variable_arg.cpp:25:5: note: in instantiation of function template specialization \'sum_super_cool<int, int, std::vector<long>>\' requested here
    sum_super_cool(1, 2, arr);
    ^
1 error generated.
  • 可变参数函数(使用 ...)不同于可变参数模板(Args ...)。您可以传递给可变参数函数的类型是有限的。在这种情况下,转发会很奇怪,因为您不需要按值传递任何内容,或者您​​需要了解更多关于参数类型的信息。
  • @JeffGarrett 我补充了我的问题,写了一个demo,显示同样的错误,我怎样才能改变我的代码用clang编译成功,使用gcc构建成功并运行成功。
  • 您不能简单地 reinterpret_cast 将函数从一种类型转换为另一种类型并期望它能够工作。 g++ 生成的代码“似乎”可以工作的事实只是巧合:显示的代码表现出未定义的行为。
  • 我将variadic function pointer 更改为function pointer,而不使用reinterpret_cast。我运行成功。但是,在我的代码中,如果我不使用reinterpret_cast。我将更改太多代码。是否有任何方便的方法替换@987654333 @

标签: c++ compiler-errors c++17 clang


【解决方案1】:

为什么不也将函数作为模板参数传递:

#include <iostream>
#include <string>
#include <vector>

bool save(int a, std::vector<long> arr)
{
    std::cout << a << '\n';
    std::cout << " hello \n";
    return true;
}

template <typename T, typename Callable, typename... Args>
bool sum_super_cool(T v, Callable ins_func, Args&&... args)
{
    std::cout << "pre\n";
    return ins_func(std::forward<Args>(args)...);
}

int main(int argc, char** argv) {
    std::vector<long> arr;
    arr.push_back(123);
    sum_super_cool(1, save, 2, arr);

    return 0;
}

这个works fine 没有任何reinterpret_casting voodoo。那几乎总是一个巨大的红旗!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 2014-10-17
    • 1970-01-01
    相关资源
    最近更新 更多