将va_start宏与此参数一起使用是否安全?

use*_*693 18 c++ variadic language-lawyer c++03

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

如果我使用普通的可变参数函数,则需要一个伪参数才能...访问其余参数。我知道可变参数宏之前不需要参数,...但我不希望使用它。如果我使用成员函数,则它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);
Run Code Online (Sandbox Code Playgroud)

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

Ser*_*sta 20

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

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

  • 如果未定义,那么我会进一步讲,它不仅会在不同的实现上导致不同的结果,而且会在同一实现上产生不同的运行。 (2认同)
  • @cadaniluk现实世界中的实现比标准要求的要一致得多,无论其扩展名是否已记录。仅仅依靠它就可以提供不可移植的代码。 (2认同)
  • @SergeBallesta:一些现实世界中的编译器编写者试图使它们比标准所要求的更加一致。其他人则更倾向于将一致的行为视为“错过的优化机会”,而不管一致的行为是否可能有用,或者“优化”是否可能提供任何真正的好处。 (2认同)