Thread: question regarding predefined macros

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    16

    question regarding predefined macros

    Hi all,

    Learning from some examples when i see these macros being. I am not sure what there are for even after i looked at the MDSN documentation. Please explain to me. Thnx!

    #if !defined(AFX_LIVEVIDEO_H__70943714_3422_4F6A_B79A_ DD84D6EECF17__INCLUDED_)
    #define AFX_LIVEVIDEO_H__70943714_3422_4F6A_B79A_DD84D6EEC F17__INCLUDED_

    I have totally no idea what is trying to be defined here with the lines above.

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    and what is this for? _DEBUG is so that when compiling with /LDd, /MDd, /MLd, and /MTd. That's all i know, which i am not sure what it means either.

    Thanks in advance!

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    [edit] Perhaps I should provide some background here.

    Macros can be defined with the preprocessor directive #define. The preprocessor does text substitution (search-and-replace) in the initial stage of compilation. So with a source file like
    Code:
    #define NUMBER 3
    
    int x = NUMBER;
    the compiler (after the preprocessor is finished) sees
    Code:
    int x = 3;
    Macros can be undefined with #undef.
    Code:
    #undef NUMBER /* nothing here */
    Inclosing code in a #if directive causes the code to be removed entirely if the expression is false, or left in place if the expression is true. For
    Code:
    #if 0
        printf("Hello\n");
    #endif
    the complier would see nothing; whereas with #if 1 or some other true expression the compiler would see the printf() statement.

    Macros can be tested for defined-ness with #if defined(MACRO) or #ifdef MACRO, which are functionally equivalent.

    The inverse, of course, is #if !defined(MACRO), which is the same as #ifndef MACRO.

    You can also use #elif and #else; and an if-elif-else chain must end with a #endif. There's no #endif after each #if, #elif, and #else -- just one at the end.
    Code:
    #if VERSION > 2
        #ifdef DEBUG
            whatever
        #elif defined(SOMETHING)
            something
        #endif
    #else
        #error Version too old
    #endif
    As you can see, preprocessor directives can be nested.

    Anyway, there's a quick introduction to preprocessor directives. There are lots of others, like #error (which generates a compiler error), #line, which changes the line number, etc. Check some documentation for details. [/edit]

    Code:
    #if !defined(AFX_LIVEVIDEO_H__70943714_3422_4F6A_B79A_ DD84D6EECF17__INCLUDED_)
    #define AFX_LIVEVIDEO_H__70943714_3422_4F6A_B79A_DD84D6EEC F17__INCLUDED_
    They are called inclusion guards. They're used to prevent a header file from being included multiple times. The first time a header file is included, the macro is not defined, so the header file defines the macro and then the rest of the header file follows. The following times the header is included, the macro is defined, so #if !defined(MACRO) is false, and the header is equivalent to a blank file.

    Inclusion guards can prevent many types of errors and are essential for projects with more than a few header files.

    The common idiom (which is exactly the same thing) is
    Code:
    #ifndef HEADER_H
    #define HEADER_H
    
    /* ... */
    
    #endif
    Last edited by dwks; 07-13-2007 at 08:54 PM.
    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.

  3. #3
    Registered User
    Join Date
    Jul 2007
    Posts
    16
    Ok.. so it is just saying that:

    since the macros is indeed not include,

    define the macros,

    and the macros is in fact the rest of the header file.

    Is my understanding correct?

    And also you mentioned the common idiom. That means that the macros name can actually be just any name instead of that:

    AFX_LIVEVIDEO_H__70943714_3422_4F6A_B79A_ DD84D6EECF17__INCLUDED

    Am i right here again?

    Thanks a lot dwks.

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by ang_ks View Post
    Ok.. so it is just saying that:

    since the macros is indeed not include,

    define the macros,

    and the macros is in fact the rest of the header file.

    Is my understanding correct?
    Not quite. There are two cases.

    The first case is that the header file has not been included before. In this case, the macro is defined as something with the #define statement, and then the rest of the header file follows. The remainder of the header file is completely unrelated to the inclusion guard macro.

    Then, if the macro has already been defined, and thus the header file has already been included, the preprocessor removes the code inside the #if !defined() or #ifndef, because the expression was false. All the compiler sees is an empty file, because everything else has been removed.

    Note that with the statement
    Code:
    #define HEADER_H
    the macro HEADER_H is being defined as an empty string. The mere fact that it is defined is enough to trigger the inclusion guard. It doesn't have to be defined as anything in particular.

    And also you mentioned the common idiom. That means that the macros name can actually be just any name instead of that:

    AFX_LIVEVIDEO_H__70943714_3422_4F6A_B79A_ DD84D6EECF17__INCLUDED

    Am i right here again?

    Thanks a lot dwks.
    Yes, macros can indeed be given any name, subject to restrictions, of course. You can only use upper- and lower-case letters, numbers, and underscores; and the first character has to be a letter of either case. You can't use _HEADER_H -- well, you could, but names beginning with _X are reserved -- nor 0something, which could be mistaken for a number, since 12L is a number and 12.324F is a number.

    There's a wikipedia entry on inclusion guards, though it isn't very extensive: http://en.wikipedia.org/wiki/Include_guard
    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.

  5. #5
    Registered User
    Join Date
    Jul 2007
    Posts
    16
    Ok i got this. Thanks a lot again.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Just to clarify the names that are always reserved to the implementation (and hence names that you should not use as your own identifiers)

    Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.

    Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The DEBUG_NEW stuff is used for detecting memory leaks. It is placed in source files and replaces new with DEBUG_NEW. DEBUG_NEW is defined somewhere else and basically stores file and line information for every time you call new in your program to allocate memory. This is done so that if you don't call delete and free the memory, you will get a message in the output indicating that memory was leaked with the file and line of the place that called new. It is very helpful in debugging memory leaks.

    It is not a standard thing, though, Visual C++ only probably. You also have to do some other work to your code to get it to work, you can't just plop that into a small console app and expect it to work. I think CRTDetectMemoryLeaks or something like is what you would look for if you ever wanted to add this to your own app.

    >> AFX_LIVEVIDEO_H__70943714_3422_4F6A_B79A_ DD84D6EECF17__INCLUDED
    VC++ uses this format (including a GUID) for header guards it generates. That's why it looks so much different than HEADER_H. The point is that it should be unique so that no two headers included by a source file have the same header guard. If you have a library that has a file called options.h and you have a file called options.h in your code, then you include both files and they both have OPTIONS_H as their include guard, then you will have problems. This will be rare occurrence, but adding the GUID makes it almost impossible.

    Also note that this name has a double underscore, and is therefore reserved for the implementation. That's ok because it was generated by VC++ (the implementation).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question about macros
    By lazyme in forum C++ Programming
    Replies: 19
    Last Post: 04-27-2009, 10:10 PM
  2. Order of execution of preprocessor macros
    By DL1 in forum C Programming
    Replies: 2
    Last Post: 04-02-2009, 06:52 PM
  3. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Macros question
    By anson1999 in forum C Programming
    Replies: 12
    Last Post: 03-08-2003, 10:30 PM