In order to avoid "magic numbers", I usually use a #define as necessary. However, I've been told to avoid this because of the issue of typesafety, and instead to use const variables. The below code is not an actual example of this, its just to illustrate my point
#define DEGREES_PER_REVOLUTION 360
int angle = 450;
int cycles = angle/DEGREES_PER_REVOLUTION;
Instead of the above, I have been advised to do the below...
const int DEGREES_PER_REVOLUTION = 360;
int angle = 450;
int cycles = angle/DEGREES_PER_REVOLUTION;
So my question is this: why not (carefully) use #define? Is there a non-trivial level of overhead in the second approach? Also, if I would like to change the constant (not in this case of course), it seems easier to change the #define rather than going to each declaration of the const int to change it.
As you state when you use a define you must be careful. Using a const variable the compiler enforces type safety.
Is there a non-trivial level of overhead in the second approach?
Both are compile time constants, so there will be no difference in run time performance.
Also, if I would like to change the constant (not in this case of course), it seems easier to change the #define rather than going to each declaration of the const int to change it.
What? You should only have one const to change, exactly as the #define. To change the value using the define you change:
I mean in the event that you use this constant within different scopes, in different areas.
But that would also apply in the case of a #define.
There's no reason why a #define must appear at the top of the code, it could be placed anywhere, just like the const.
Similarly, there's no reason why the const must be placed somewhere deep in the code. If it's likely to be referenced from multiple places (like for example the value of PI), then it's better put at the top. And similarly if the value of the const may need to be frequently changed, again place it at the top for easy access.
Well, global variables are generally (but not always) bad practice.
In the case of a constant, it would probably be bad practice to define an identical constant serving an identical purpose in multiple places within the code. Doing that risks the value (and perhaps type) of each one being different. That could make the global version the best option.
As soon as you make hard and fast rules about what is good and bad practice someone is likely to come along with a counter example, so each case needs to be judged on its own merits.
At any rate, I don't think any of these concerns can be regarded as an argument in favour of #define. To avoid doing something because you've been told it's bad practice, and to instead do something which is much worse practice is hardly logical.
a const is not a (global) variable it is in fact const. No memory is used until you're doing something with that const. You can place it in headers as well