2

So I'm writing a library and I want to define a constant that will have the value of pi. I was thinking of defining a static const float pi = 3.14; in a pi.h file.

However, I'm almost sure that's not the way to do it because I've read that you shouldn't define variables in header files.

Another way I thought was to declare an inline function that returns the value of pi but that's awkward to work with.

Another way (I think) is to put it in pi.cc compile it into the library and then use extern static const float pi; in whatever file you are using pi with and of course link those files with the library.

What's the best way of doing this? The standard library would probably define a macro but I think a constant is better.

s5s
  • 11,159
  • 21
  • 74
  • 121
  • Where did you see M_PI? I looked at the reference http://www.cplusplus.com/reference/clibrary/cmath/ and couldn't see it. – s5s Apr 17 '12 at 19:05
  • Never mind, it's in my implementation, but isn't part of the standard. – chris Apr 17 '12 at 19:06
  • 1
    Related: http://stackoverflow.com/questions/1727881/how-to-use-the-pi-constant-in-c – K Mehta Apr 17 '12 at 19:07
  • As Kshitij Mehta indicates, you should use `M_PI` - it may not be ANSI/ISO standard, but it is a POSIX standard and is commonly supported by other compilers as well (though you might have to configure a "feature macro" to get it defined - for example, `_USE_MATH_DEFINES` on MSVC as Kshitij's link indicates). – Michael Burr Apr 17 '12 at 19:26
  • `M_PI` in in the XSI (Unix) option, not POSIX base. On systems that don't purport to support these standards, I'm not sure it's the best idea to go looking for other system-specific macros to get it defined. Why not just write it out yourself? It's not like the value of pi is going to change anytime soon.... – R.. GitHub STOP HELPING ICE Apr 17 '12 at 21:50
  • 1
    @R. - OK I'll buy that. But things like http://stackoverflow.com/questions/1352784/preprocessor-examples-in-c-language and http://stackoverflow.com/questions/2777541/static-const-double-in-c scare me a little. But maybe they're just throw away example code that isn't meant to have been serious in the first place. Then again, there's always http://www.straightdope.com/columns/read/805/did-a-state-legislature-once-pass-a-law-saying-pi-equals-3 I even managed to screw it up in the original edit of this answer: http://stackoverflow.com/a/9040612/12711 – Michael Burr Apr 17 '12 at 23:13
  • I was assuming OP would be smart enough to define it correct to `DECIMAL_DIG` places, but perhaps that's asking too much... +1 to your comment, made me laugh. :-) – R.. GitHub STOP HELPING ICE Apr 18 '12 at 01:50

6 Answers6

1

My suggestion is to place the constant in a header file. The constant will give the value type information which is a good thing.

Since the constant is not a variable, it can be placed in a header file.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • And then presumably I will have to treat the header as a .cc file and compile it so that I can add it to the library? That's what annoys me a bit - seeing .h files being compiled like .cc files in the Makefile :) – s5s Apr 17 '12 at 19:11
  • @s5s, The .h files are only compiled when a .cc file requests it so (via an include.) Remember that the .cc files are the compilations units. – Chris A. Apr 17 '12 at 19:13
  • @s5s constants have internal linkage by default (you don't need the `static`) - which means there is never any problem including them in a header file, no matter how often it is included. – Alan Stokes Apr 17 '12 at 19:14
1

you need to pull in the macro #define _USE_MATH_DEFINES as well

How do I access math constants (eg. M_PI) in Visual C++ 2008?

Community
  • 1
  • 1
nate_weldon
  • 2,289
  • 1
  • 26
  • 32
1

One reason to not put a constant in a header file is to avoid recompiling the code using the library (rather than just re-linking) if the constant changes. This reason doesn't apply to constants such as π that never change as a program is maintained.

There is an additional issue if the constant is a floating point value. C++ requires that floating point constants have storage assigned to them and that they be initialized in a .cpp file, not a .h file. This can makes them the constants less efficient than the equivalent inlined functions. This is why the Boost library uses inline functions. See this answer.

So for your case, the best bet is probably to use the Boost library, or if you don't want to take the dependency, to just make an inline function that does the same thing.

Community
  • 1
  • 1
Edward Brey
  • 40,302
  • 20
  • 199
  • 253
0

I see constant variables defined in header files often. Your idea of doing that seems reasonable to me. Making it static seems OK as well.

01100110
  • 2,294
  • 3
  • 23
  • 32
0

You also could divide your PI constant to two files, header and implementation. Having declaration and implementation separated you could change the value of pi (to more precise for example) without changing the interface.

This could by simple pi.h file:

extern float pi;

and pi.c:

float pi = 3.14;
marekb
  • 141
  • 1
  • 3
0

I would make it static const but not extern and place it in a header file. static const tells the compiler that it's a constant variable accessible only in the current compilation unit. This allows the compiler to optimize away any actual storage for it and just use the value directly.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299