包装C API函数将指针返回到宏调用

时间:2016-11-17 21:44:10

标签: c++ c++11 c-preprocessor

我正在尝试将C API函数包装在某些情况下返回int,而在其他情况下将指针返回到宏中,这将检查条件并提供诊断并在出现错误时抛出异常。对于返回int的函数,它很简单,因为我不需要int

#define CALL_INT( name, ... ) do { \
        if( !name( __VA_ARGS__ ) ) throw std::runtime_error( #name " failed" );
     } while(0)

  // using it
  CALL_INT( foo, arg );

但是对于返回指针的函数来说并不那么简单,因为我需要检查指向nullptr的指针,然后将其指定给我的指针。所以可以编写类似的宏,所以这个表达式可以工作:

auto ptr = CALL_PTR( foobar, arg1, arg2 );

即它会生成代码,调用foobar( arg1, arg2 )检查nullptr的结果,如果没有错误发生则可以分配。

2 个答案:

答案 0 :(得分:3)

真正的解决方案是:不要使用宏。只要写下你想做的内联。你和其他所有人以后都会感谢你自己。

文字解决方案是立即调用lambda:

{{1}}

答案 1 :(得分:1)

魔法越少越好

#define VERIFY( ... ) \
  [&](){
     auto r = __VA_ARGS__;
     if (!r) throw std::runtime_error( #__VA_ARGS__ " failed" );
     return r;
  }()

这需要一个表达。它运行它。然后测试它并在它失败时抛出。

如果失败,则包括throw中的整个表达式。

然后返回它。

由于VERIFY(bob)正在做bob,所以不那么神奇了。你可以做到

int x = VERIFY( call(a,b,c) );

VERIFY( y = call(a,b,c) );

或其他什么。主代码运行在那里;只有断言包装器失败时才会丢失。

VERIFY也称为通常执行此操作的宏。