2

I'm wondering what is the "best practice" to define the complex constant "i" in C++.

I know that the "#define vs const in C++" question has been asked multiple times, and that the general answer is that it's best to use const.

However, I'm thinking that it makes sense to use #define instead of const to define mathematical constants (such as "i" or "pi"), because we don't think of them as variables, but "absolute constants" (in the accepted answer here, one can read: "A constant defined with the const qualifier is best thought of as an unmodifiable variable."). Also, I see that in the math.h library, constants are defined this way, e.g. #define M_E 2.71828182845904523536028747135266250 /* e */.

So I'm wondering, how do C++ programmers usually define the complex constant i?

Lastly, I have a small issue with my current code #define I std::complex<double>(0.0, 1.0): precompilation causes a name clash with a Qt library that I use (as soon as I enable C++11 support).

Community
  • 1
  • 1
Seub
  • 2,451
  • 4
  • 25
  • 34

1 Answers1

2

Best practise is to declare a static const instance, with either a distinctive name or in a namespace.


Your #define does not define a mathematical constant. It defines a macro which expands to std::complex<double>(0.0, 1.0). Why are they different?

1. Scope

Every time the compiler finds a token called I, whether it could be a variable name or not, will be replaced. It doesn't matter if it's a type name, a template parameter, a variable or a function argument - it will be replaced. It doesn't matter if it's in a namespace either, since the preprocessor doesn't understand them. You've already seen this break Qt, which is precisely the reason macros are generally deprecated for declaring constants.

Where they are used, it's vital to make sure the name is unique - but there's no easy way to do this.

2. Semantics

If I declare a static constant variable (ie, one that doesn't vary despite the name), it's useable just like any instance of that type - and a smart optimizer can probably avoid loading the global. However, the macro declares a new anonymous temporary each time it is referenced. There will be at least some cases where the duplicate instances can't be elided.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • I thought static is not needed in C++? – Seub Aug 18 '13 at 17:18
  • @Seub: `static` has different purposes depending on how it is used. Inside a class, it allows one instance of the member. When declared in the scope of a translation unit (free standing), it limits the visibility (access) to the item. – Thomas Matthews Aug 18 '13 at 17:43
  • I mean, I thought `static const` is not needed, just `const` will do? – Seub Aug 18 '13 at 18:50
  • Yes, that'll be fine, I just added a useless `static` from habit. – Useless Aug 20 '13 at 09:30