基于#define变量类型的条件编译

时间:2019-01-25 12:38:56

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

以下是我尝试实现的剪切版本。我正在对某个单词做一些算术运算,我想使用__builtin_clrsb,并且用户将int用作单词类型,然后使用慢速算法进行编译。无论__builtin_clrsb是哪种类型,后续都使用WORD进行编译。

代码使用C ++ 11,但是在嵌入式系统上运行,因此我无权使用大多数std::工具。

#if !defined(WORD)
  #define WORD int
#endif

template<size_t S, typename word = WORD>
class my_class {
  ...
  ...
  ...

  size_t do_stuff(){
#if WORD == int && defined(__builtin_clrsb)
    //compile with  __builtin_clrsb
#else
   //comple with slow method
#endif
  }
};

2 个答案:

答案 0 :(得分:1)

我认为您不应该这样做:

  size_t do_stuff(){
#if WORD == int && defined(__builtin_clrsb)
    //compile with  __builtin_clrsb
#else
    //comple with slow method
#endif
  }

相反,您应该使用C ++模板专业化来解决此问题。

template<class D, size_t S, class word>
struct my_class_do_stuff_impl {
  D& self() { return *static_cast<D*>(this); }
  D const& self() const { return *static_cast<D const*>(this); }
  size_t do_stuff(){
    //compile with slow method
    //use `self()` instead of `this` to access members of `my_class`
  }
};
#if defined(__builtin_clrsb)
  template<class D, size_t S>
  struct my_class_do_stuff_impl<D,S,int> {
    D& self() { return *static_cast<D*>(this); }
    D const& self() const { return *static_cast<D const*>(this); }
    size_t do_stuff(){
      //compile with  __builtin_clrsb
      //use `self()` instead of `this` to access members of `my_class`
    }
  };
#endif
template<size_t S, typename word = WORD>
class my_class:
  public my_class_do_stuff_impl<my_class<S,word>, S, word>
{
  // don't include do_stuff here
  // if you call do_stuff, do this->do_stuff()
};

有很多这样做的理由。一个是WORD为int不会强制my_class的wordint。另一个是我们可以在预处理程序之外执行此操作,所以应该这样做。

答案 1 :(得分:0)

麻烦

#if WORD == int && defined(__builtin_clrsb)

在C ++中,==适用于值而不是类型的事实是,#if是在预处理步骤而不是编译过程中求值的,并且预处理器实际上不知道{ {1}}是。 int的规则是,在替换所有宏并评估所有#if测试之后,除defined()之外的所有类似标识符的标记(即使是C ++关键字)也将被更改,该标记没有命名宏到true以便评估0

因此,在用其他类型替换#if(例如WORD)并将short评估为defined之后,预处理器将保留

1

,然后关键字更改为#if short == int && 1

0

是真的。

我推荐Yakk's answer中显示的模板解决方案。


[但是,如果有人在乎,这是我看到这个答案之前在这里遇到的基于预处理程序的黑客。仅在#if 0 == 0 && 1 不包含WORD之类的空格时有效。]

long long