开发者

Disabling C++ code without macros

开发者 https://www.devze.com 2023-02-28 09:23 出处:网络
I hate macros. I\'m trying to avoid using them as much as I can, but I occasionally need them to enable / disable features in my code. Typically:

I hate macros. I'm trying to avoid using them as much as I can, but I occasionally need them to enable / disable features in my code. Typically:

#ifdef THREAD_SAFE
  typedef boost::mutex Mutex;
  typedef boost::mutex::scoped_lock ScopedLock;
#else
  typedef struct M {            } Mutex;
  typedef struct S { S(M m) { } } ScopedLock;
#endif

This way I can leave my actual code unchanged. I'm trusting the compiler to remove the placebo c开发者_开发技巧ode when the macro is undefined.

I'm aware that template specialization could be a solution, but that would involve a lot of rewriting / code duplicating.

No need to be a C++ expert to guess there's something wrong with the way I'm cheating on the compiler. I'm looking for a better solution.


What you are using aren't macros, but normal preprocessor capabilities. Also, you're not relying on the compiler, but the preprocessor.
The compiler will only ever see one of the two versions, the other gets eliminated before the compilation step. Nothing wrong with using the preprocessor to do (conditional) inclusion/exclusion of code. It isn't any kind of "cheating", that's totally what the preprocessor is there for.


Macros are the only good way to get information from the build system into the program. The other alternative is writing your own code-generation scripts, or tools like SWIG.

The problem I see here is the unnecessary use of typedef. I think this is better because it limits the introduction of new symbols (single-letter ones!), and keeps code looking more canonical.

#ifdef THREAD_SAFE
  using boost::mutex;
#else
  struct mutex {
      struct scoped_lock {
          scoped_lock(mutex const &m) { }
      };
  };
#endif


While I wouldn't recommend it for this simple case, you can separate out the stuff that changes and implement it in a separate translation unit, then let your build system select the right file. This would be more appropriate when there are more sweeping changes than just making a variable go away, like pulling out Windows library calls for the Unix equivalent.

0

精彩评论

暂无评论...
验证码 换一张
取 消