c++ - 将此作为参数使用 va_start 宏是否安全?

标签 c++ language-lawyer c++03 variadic

我必须在嵌入式应用程序中使用 IAR 编译器(它没有命名空间、异常、多重/虚拟继承、模板有点限制并且仅支持 C++03)。 我不能使用参数包,所以我尝试使用可变参数创建成员函数。 我知道可变参数通常是不安全的。但是在 va_start 宏中使用 this 指针是否安全?

如果我使用普通的可变参数函数,则在 ... 之前需要一个虚拟参数才能访问剩余的参数。我知道可变参数宏在 ... 之前不需要参数,但我不想使用它。 如果我使用成员函数,它在 ... 之前隐藏了 this 参数,所以我尝试了它。:

struct VariadicTestBase{
  virtual void DO(...)=0;
};

struct VariadicTest: public VariadicTestBase{
  virtual void DO(...){
    va_list args;
    va_start(args, this);
    vprintf("%d%d%d\n",args);
    va_end(args);
  }
};

//Now I can do
VariadicTestBase *tst = new VariadicTest;
tst->DO(1,2,3);

tst->DO(1,2,3); 按预期打印 123。但我不确定这是否不仅仅是一些随机/未定义的行为。我知道 tst->DO(1,2); 会像普通的 prinf 一样崩溃。我不介意。

最佳答案

标准中没有指定该行为,因此该构造仅调用正式的未定义行为。这意味着它可以在您的实现中正常工作,并在不同的实现中导致编译错误或意外结果。

非静态方法必须传递隐藏的 this 指针这一事实并不能保证 va_start 可以使用它。它可能是这样工作的,因为在早期,C++ 编译器只是将 C++ 源代码转换为 C 源代码的预处理器,而隐藏的 this 参数由预处理器添加以供 C 使用编译器。并且可能出于兼容性 的原因对其进行了维护。但我会尽量避免在关键任务代码中出现这种情况......

关于c++ - 将此作为参数使用 va_start 宏是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55728743/

相关文章:

c++ - 如何在不等待新数据到达的情况下使用 boost::asio 的 async_read_some() 读取所有可用数据?

c++ - 从 vector 中删除 vector::end

c++ - 是否允许在模板特化时从 int 转换为 long (此代码应该编译)?

c++ - 默认构造函数的宏是否可能,待定的编译器支持?

c++ - 引用声明是否为引用对象引入了一个新名称?

c++ - 如何对 vector 进行二进制搜索以查找具有特定 id 的元素?

c++ - boost char_ptr_holder 实例化

c++ boost从磁盘并行获取文件

c++ - 使用 C++ 从不同大小的 blob 生成热图

C++14 警告 : too many template headers for variable (should be 0)