• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Nairou

Is #ifdef still preferred?

9 posts in this topic

Reading "Effective C++" by Scott Meyers, he talks about the disadvantages of #define and how you should almost always use const or inline instead, relying on the compiler to optimize your code for the same result. That got me wondering, what about things like #ifdef? For example, will the compiler optimize the following two examples into the same thing? If so, I wonder if there are any advantages of one over the other. The second seems more friendly to me, less hackish than the first.
#define IS_SERVER 1

// ...
#ifdef IS_SERVER
    // ... server code ...
#endif
// ...
const int isServer = 1;

// ...
if ( isServer ) {
    // .. server code ...
}
// ...
0

Share this post


Link to post
Share on other sites
Quote:
Original post by Nairou
For example, will the compiler optimize the following two examples into the same thing?

For most modern compilers, yes. To make sure of it, though, it's a good idea to force internal linkage of constants used in this way (by declaring the variable as static, or putting it in an anonymous namespace). The compiler is much less likely to be able to do this with constants defined in a different translation unit.

However, the code still needs to be syntactically and semantically correct. So using const variables may not be the right approach if you're implementing different functionality for each branch, as you seem to be doing here.
0

Share this post


Link to post
Share on other sites
The idea of using #define for constants is bad. But using pre-processor things for determining platform and such is what you must do if you want easily configured code.

to explain further, this is often considered "bad":

#define PI 3.14156




it is now generally preferred to be

const FLOAT PI = 3.14159f;





however, your example of using const for isServer is horrible. That's the kind of thing you want to control in your compiler setttings (i.e. you set up a configuration for client, one for server, one for linux, etc). With the const example you have to actually change code every time you want to compile for a different platform.

-me
0

Share this post


Link to post
Share on other sites
Meyers is talking about #define for constants, not for preprocessor control over code generation, which is what your example is. The first method is the correct way to handle the situation.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by Nairou
That got me wondering, what about things like #ifdef? For example, will the compiler optimize the following two examples into the same thing? If so, I wonder if there are any advantages of one over the other. The second seems more friendly to me, less hackish than the first.

Most popular compilers will elide the unreachable code, making the two implementations act as if they do the same thing.

There are fundamental differences, however, and most of the advantages go to the preprocessor construct in this case.

(1) A preprocessor value can be set extralingually (usually through a command-line option to the compiler, such as -DIS_SERVER=1). Thus, you can autodetect and set various compile-time options, something you can't do using C++ constants.

(2) Code within an #ifdef block is never even seen by the compiler. That means if you have, say, functions calls that do not exist on some platforms then you can still compile your code. For example,

#ifdef _WIN32
int istat = WSAStartup( ... );
#endif

You can't do that at all using C++ constants. You would have to revert to some kind of wacky template specialization.

Quote:
Original post by SneftelFor most modern compilers, yes. To make sure of it, though, it's a good idea to force internal linkage of constants used in this way (by declaring the variable as static, or putting it in an anonymous namespace).

Simply putting it in an anonymous namespace forces external linkage. If you want internal linkage you will have to make it static, regardless of the namespace in which you put it (don't forget "global" is just a namespace like any other).

--smw
0

Share this post


Link to post
Share on other sites
Quote:

To make sure of it, though, it's a good idea to force internal linkage of constants used in this way (by declaring the variable as static, or putting it in an anonymous namespace).

Quote:

Simply putting it in an anonymous namespace forces external linkage.


Ok. 2 things I thought I knew about C++ questioned in this thread.

1) I thought const variables had internal linkage by default (I thought this is why you can place them in headers).
2) I also thought anything in an anonymous namespace had internal linkage. (how does one refer to something in an anonymous namespace in a different source file anyway?)

I could easily be wrong, but can anyone clarify?
0

Share this post


Link to post
Share on other sites
It looks like I was partially wrong about anonymous namespaces. Names declared in an anonymous namespace are only visible to the translation unit, but have external linkage. Of course, for this particular purpose name visibility is the important thing, so it'll work fine--as will just declaring it const, since that defaults to internal linkage.
0

Share this post


Link to post
Share on other sites
To state all the above great things as a general guidline:

In the old days of C / C++, people used the preprocessor to do anything it could do, often doing things with the preprocessor that could be done in code simply to improve compiler performance, or make the generated output more efficient (when compilers weren't as advanced).

Now, the preference is:

Use the preprocessor for anything to do with controlling compilation.

Use the compiler and language constructs for anything to do with controlling program logic and data.

Simple, easy to remember, and correct almost every time.
0

Share this post


Link to post
Share on other sites
If you have certain code for server and other code for client - maybe you can put the code in different files and use the project settings (ie. makefile) to build the right files.
In my project I have "common" files, server files and client files, and several makefiles (one for server and one for client).

But of course, it works if the code is clearly separated and doesn't solve the entire need for ifdef style compilation control.
0

Share this post


Link to post
Share on other sites
As a side note, Visual C++ 2005 will "grey out" code within #ifdef X #endif whenever X is not defined. It obviously doesn't do this when using if(x).

Also, to expand on what Bregma said, not only do you have problems with platform-specific functions, you'll also have trouble with including platform-specific headers.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0