Thread: In support of #defines

  1. #1
    </3 Segfaults
    Join Date
    Jul 2007
    Posts
    27

    In support of #defines

    They aren't good practice in general, but there is one case in which they can be justified (I think):

    Let's say you have a program that has multiple versions. You want to compare them, and don't want to have lots of windows/tabs up (too lazy or something). You can try this:

    Code:
    #DEFINE VER1 0
    #DEFINE VER2 0
    #DEFINE VER3 1
    
    #IF VER1
    //version 1 code here
    #ENDIF
    
    #IF VER2
    //version 2 code here
    #ENDIF
    
    #IF VER3
    //version 3 code here
    #ENDIF
    And I can't think of a better way to switch versions on the go. Just change the version numbers at the top of your code and you're set to compile. It even works when there's version-specific code littered all over the place. Just make sure that you make your labels something obscure that you won't use in your actual code.

    Any objections?

  2. #2
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Thats a decent way to use defines. But that can become real complicated real fast.

  3. #3
    </3 Segfaults
    Join Date
    Jul 2007
    Posts
    27
    Quote Originally Posted by prog-bman View Post
    Thats a decent way to use defines. But that can become real complicated real fast.
    Most probably. How else would you do it, though?

    Comments don't stack

    #IF 0's get lost all over your code (plus you can't keep track of what the code you're 0'ring out does, and whether you should compile it or not)

    If you erase it, you might have erased something you might want later

    If you make separate files, it's a pain to open all of them
    Last edited by Differ; 07-30-2007 at 07:00 PM.

  4. #4
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    I am just saying that it can become real complicated not that it's bad. The only other way is to implement some sort of version system where you enable/disable things in code depending on the version. Both ways aren't that fun.

  5. #5
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    This idea is perhaps the sole solution to certain implementation dependent tasks. However, most often you'd test for whether something was defined, rather than defining them all with a true or false value.
    Code:
    //#define VERSION1
    #define VERSION2
    //#define VERSION3
    
    . . . .
    
    #ifdef VERSION1
    //////
    #endif
    #ifdef VERSION2
    /////
    #endif
    //etc...
    I guess the idea is that compilers define certain macros that indicate the compiler and environment, so that code can be compiled all over the place.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  6. #6
    </3 Segfaults
    Join Date
    Jul 2007
    Posts
    27
    Quote Originally Posted by CodeMonkey View Post
    This idea is perhaps the sole solution to certain implementation dependent tasks. However, most often you'd test for whether something was defined, rather than defining them all with a true or false value.
    Code:
    //#define VERSION1
    #define VERSION2
    //#define VERSION3
    
    . . . .
    
    #ifdef VERSION1
    //////
    #endif
    #ifdef VERSION2
    /////
    #endif
    //etc...
    I guess the idea is that compilers define certain macros that indicate the compiler and environment, so that code can be compiled all over the place.
    I didn't even know that function existed. It certainly looks cleaner than my way. =)

  7. #7
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    I didn't even know that function existed. It certainly looks cleaner than my way. =)
    That function certainly does exist. In fact, if you look in any of the standard header files, you should find that it is used quite frequently for the purpose you are describing. An portion of <iostream>:
    Code:
    #ifndef _IOSTREAM_
    #define _IOSTREAM_
    #include <istream>
    
    #ifdef  _MSC_VER
    #pragma pack(push,8)
    #endif  /* _MSC_VER */
    _STD_BEGIN
    		// OBJECTS
    static ios_base::Init _Ios_init;
    extern _CRTIMP istream cin;
    extern _CRTIMP ostream cout;
    extern _CRTIMP ostream cerr, clog;
    		// CLASS _Winit
    class _CRTIMP _Winit {
    public:
    	_Winit();
    	~_Winit();
    private:
    	static int _Init_cnt;
    	};
    		// WIDE OBJECTS
    static _Winit _Wios_init;
    extern _CRTIMP wistream wcin;
    extern _CRTIMP wostream wcout, wcerr, wclog;
    _STD_END
    #ifdef  _MSC_VER
    #pragma pack(pop)
    #endif  /* _MSC_VER */
    
    #endif /* _IOSTREAM_ */
    Don't quote me on that... ...seriously

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Sounds like a poor substitute to version control systems, to me.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    It's not intended to be a substitute at all.

    Another example is platform specific code that you place in a single file. You can use #defines to separate windows code from unix/linux code. Obviously keeping separate branches for this file in a version control system makes no sense, since the code is the same for each version of your app.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Daved View Post
    Another example is platform specific code that you place in a single file. You can use #defines to separate windows code from unix/linux code. Obviously keeping separate branches for this file in a version control system makes no sense, since the code is the same for each version of your app.
    A better approach is to encapsulate the platform specific code in their own modules and build using the appropriate module for the platform. As the number of platforms you support grows, you don't want all platform-specific details shoved into a single source file.

    For instance, you have "linux-io.cpp", "win32-io.cpp," etc. which implement your platform-specific I/O routines. The makefile for Linux compiles the linux-io.cpp file and ignores win32-io.cpp. Vice versa for the Windows makefile.

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Just as a side note: GCC doesn't support uppercase preprocessor directives, and I'm sure that other compilers do not either. That is, you should use
    Code:
    #define X
    instead of
    Code:
    #DEFINE X
    Another legitimate use of #defines: debugging. When debugging mode is on, some code is compiled which makes the program easier to debug, but perhaps slows it down a lot. When you turn off debug mode, the unneccesary code can be completely skipped over by the compiler if it's inside a preprocessor #if. Something like this:
    Code:
    #ifdef DEBUG
        if(memory == NULL) std::clog << "First call or out of memory, allocating memory\n";
    #endif
    Assertions (from <cassert>) are a form of this.

    Lastly, #defines are essential as inclusion guards.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    In many cases, things are worded in the reverse. That is, #if NDEBUG is not defined...
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Daved View Post
    It's not intended to be a substitute at all.

    Another example is platform specific code that you place in a single file. You can use #defines to separate windows code from unix/linux code. Obviously keeping separate branches for this file in a version control system makes no sense, since the code is the same for each version of your app.
    Totally different ballgame. I would never suggest there is anything wrong with doing that.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    If you want an example of how complicated versioning in this manner can become just check the windows.h header file.

    It's a mess.

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Totally different ballgame. I would never suggest there is anything wrong with doing that.
    I was under the impression that something like my example was what the OP was talking about. I completely agree with you if the OP really did want to use #defines for versioning.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  2. failure to import external C libraries in C++ project
    By nocturna_gr in forum C++ Programming
    Replies: 3
    Last Post: 12-02-2007, 03:49 PM
  3. Dev-cpp - compiler options
    By tretton in forum C Programming
    Replies: 7
    Last Post: 01-06-2006, 06:20 PM
  4. Webhost with SQL2000 and PHP support....
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 02-17-2005, 02:20 PM