Global variables in comparison to #define

Started by
27 comments, last by Zoner 11 years, 9 months ago

so #undef at the bottom of the .CPP files is a good idea.

I agree with most of #3 except for doing this, as I think it's going too far. I think if I saw it being done I'd say "WTF are they doing this for???" (and I think 99.99% of other programmers would say the same (what I'm trying to say is you'll just confuse other programmers for the most part with it)). I've never heard of a compiler needing this, and I think following it just on "rumor" is going waaay too far, asking for unnecessary mental overhead in developing. Additionally, if a compiler leaks macros/identifiers it shouldn't from one translation unit to another, it's worth reporting that bug to the compiler vendor, and expecting them to fix it.


[quote name='L. Spiro' timestamp='1341672034' post='4956646']
__ (2 underscores) is a prefix reserved for the system/compiler. If you want to make absolutely sure your macros will never conflict with anything, you could add some underscores in front, but make sure it is not just 2 underscores. At work we use 3.


Anything starting with two underscores or one underscore and a capital letter is reserved for the compiler. So, anything starting with three underscores is reserved (since it also starts with two underscores) and any capitalized macro that starts with any underscores is reserved. Also, there can't be any sequence of two underscores in the identifier, even if it's not at the start. The compiler is not likely to define a macro that starts with three underscores but it is still allowed to do so.
[/quote]
+1. In addition: "Each name that begins with an underscore is reserved to the implementation for use as a name in the
global namespace." So macros simply should never start with an underscore, and no variable in the global namespace should either, even if it's followed by a lower case letter.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Advertisement

[quote name='L. Spiro' timestamp='1341672034' post='4956646']
so #undef at the bottom of the .CPP files is a good idea.

I agree with most of #3 except for doing this, as I think it's going too far. I think if I saw it being done I'd say "WTF are they doing this for???" (and I think 99.99% of other programmers would say the same (what I'm trying to say is you'll just confuse other programmers for the most part with it)). I've never heard of a compiler needing this, and I think following it just on "rumor" is going waaay too far, asking for unnecessary mental overhead in developing. Additionally, if a compiler leaks macros/identifiers it shouldn't from one translation unit to another, it's worth reporting that bug to the compiler vendor, and expecting them to fix it.
[/quote]


Actually, #undefing your macros is still a good idea, in case someone gets antsy about build times and tries to deploy a unity build structure to your C/C++ project. Leaving macros defined all over the place can get incredibly painful in unity builds.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


[quote name='Cornstalks' timestamp='1341707356' post='4956770']
[quote name='L. Spiro' timestamp='1341672034' post='4956646']
so #undef at the bottom of the .CPP files is a good idea.

I agree with most of #3 except for doing this, as I think it's going too far. I think if I saw it being done I'd say "WTF are they doing this for???" (and I think 99.99% of other programmers would say the same (what I'm trying to say is you'll just confuse other programmers for the most part with it)). I've never heard of a compiler needing this, and I think following it just on "rumor" is going waaay too far, asking for unnecessary mental overhead in developing. Additionally, if a compiler leaks macros/identifiers it shouldn't from one translation unit to another, it's worth reporting that bug to the compiler vendor, and expecting them to fix it.
[/quote]


Actually, #undefing your macros is still a good idea, in case someone gets antsy about build times and tries to deploy a unity build structure to your C/C++ project. Leaving macros defined all over the place can get incredibly painful in unity builds.
[/quote]
Are you and I talking about the same thing (#undef at the bottom of the .CPP files)? Like I said, I agree with most of #3 (cleaning up your macros is a good thing). But I think cleaning them up at the end of a source file is a waste of time and space, and I can't see how that would decrease compile times at all.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
The whole idea of a "unity build" is to #include several of your .cpp files into one "master" translation unit, which does in fact help with compile times in some cases. (My personal feeling is that unity builds are a bandage over terrible header and dependency management issues, but that's another debate.)


Consider the following code:

// Foo.cpp
#define bool int

bool FooFunction() {
return 1;
}

// Bar.cpp
bool BarFunction() {
return true;
}

// Unity.cpp
#include "foo.cpp"
#include "bar.cpp"


This is typical of how unity builds are implemented. Clearly, in this example, you can expect the #define to cause havoc.

If you use unity builds, it's generally a very good idea to keep macros tightly scoped and #undef them as soon as possible. If that happens to be at the end of a .cpp file, so be it.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


*snip*

Ah, I see. I wasn't familiar with the term "unity build" (though I'm familiar with the concept; I'm more familiar with the term "amalgamation," thanks to SQLite) and had Unity (as in Unity3D) come to mind. Yes, I must agree then iff a unity build is being done. But L. Spiro was talking about macros spilling over from one translation unit to another, and in this normal workflow with multiple translation units I think it's pointless.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
I said to #undef them at the bottom but that was not to be taken too literally. I personally #undef them at the earliest possible moment, almost always being inside the same function in which they are created (even if I have a family of related functions in a row that end up redefining the same macro the same way), but I only wanted to mention the most common case where people “leak” macros, where you might #define some macro at the top of the .CPP, and then just let it go.

Definitely, if you are defining something inside a function, #undef at the end of the function, not the end of the file.

Also, having macros leak into other translation units (in a normal environment, not unity builds) is of course a special rare case, and is not the motivation for the #undef.
That is only a secondary point, since it is unlikely you will ever even encounter that.



L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

#define: constant
global variable: variable

#define: constant
global variable: variable


*Sigh*

const int i = 123; // constant
int i = 123; // global variable
#define i 123 // technically creates a literal, not a constant, everywhere it is replaced, with no meaningful name for the compiler to use
In addition, it's worth noting that "const" has certain limitations; compare:
[source lang="cpp"]struct C
{
inline static int getval() {return 4;}
};
const int MAX=1024;
const int MIN=C::getval();
[/source]
"MAX" is a constant integral expression (can be used as an array-size in array declarations, as a case label in switch statements, etc.), while "MIN" is not.
See: http://www.devx.com/...tion/33327/1954

In C++11 there's a new declaration specifier, "constexpr", which allows you to solve this problem and, for example, do this:
[source lang="cpp"]constexpr int getDefaultArraySize (int multiplier)
{
return 10 * multiplier;
}
int my_array[ getDefaultArraySize( 3 ) ];
// perfectly legal, "getDefaultArraySize( 3 )" is a constant integral expression equal to 30 at compile-time
[/source]

See: http://www.cprogramm...-constexpr.html

More:
http://en.cppreferen...guage/constexpr
http://cpptruths.blo...texpr-meta.html
http://thenewcpp.wor...1/14/constexpr/
http://kaizer.se/wik...onstexpr_foldr/

[quote name='Acotoz' timestamp='1341721110' post='4956821']
#define: constant
global variable: variable


*Sigh*

const int i = 123; // constant
int i = 123; // global variable
#define i 123 // technically creates a literal, not a constant, everywhere it is replaced, with no meaningful name for the compiler to use
[/quote]

Alright, let's have another case here.

what happens if I do this?

#define CYCLE for (int i = 0; i < 25; i++)

CYCLE will be defined by that little instruction, so that is not a literal, not a constant, not a variable.

Good luck

This topic is closed to new replies.

Advertisement