Thread: C/C++ preprocessor directives

  1. #1
    Spam is Good
    Join Date
    Jan 2009
    Location
    In a cave on Mars
    Posts
    37

    C/C++ preprocessor directives

    Which of the following statements correctly describe C preprocessor directives in C++?

    A. Preprocessor directives are processed before macros are expanded.
    B. Any number of #else directives can be used between an #if and an #endif.
    C. The #pragma directive is machine-independent.
    D. The #import directive is used to copy code from a library into the
    program's source code.
    E. The #include directive is used to identify binary files that will be
    linked to the program.

    Well I'm sure I know all these, but am a little unsure about A and C. Now:
    * From memory, macros are processed before directives, so A is INCORRECT.
    * B is INCORRECT because you can't do #if #else #else #endif
    * C is CORRECT since "The #pragma directives offer a way for each compiler to offer machine- and operating system-specific features while retaining overall compatibility with the C and C++ languages." from http://msdn.microsoft.com/en-us/libr...05(VS.71).aspx
    * D is obviously CORRECT
    * E is obviously CORRECT

    Could someone please clarify my answer. Thx.

  2. #2
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    Not quite. Who is giving you these awful questions? They need to spend more time teaching good design/coding techniques.

    A. I don't know about A. Isn't the expanding of macros part of the preprocessor?
    B. You're right.
    C. Read the first paragraph of the page you linked to.
    D. Never used it.
    E. Binary? Linking? No -- #include expands one text file into another.

    So there's my two cents. Now stick around while one of the gurus corrects us.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  3. #3
    Spam is Good
    Join Date
    Jan 2009
    Location
    In a cave on Mars
    Posts
    37
    Quote Originally Posted by CodeMonkey
    Who is giving you these awful questions?
    Some online quiz.

    Quote Originally Posted by CodeMonkey
    They need to spend more time teaching good design/coding techniques.
    Tell me about it. My guess is this online quiz was setup by a webdev coder and as we all know they don't really know about real coding - and hence have developed crap questions - but I must say its had the hardest (or hardest to understand) questions I've found online.

    Quote Originally Posted by CodeMonkey
    A. I don't know about A. Isn't the expanding of macros part of the preprocessor?
    Yep, the preprocessor expands macros and directives, but the order of expansion (or IIRC the correct term is "Phases of Translation") is what the question is asking (Well that is how I read it).

    Quote Originally Posted by CodeMonkey
    C. Read the first paragraph of the page you linked to.
    So its incorrect, since #param is machine dependant.

    Quote Originally Posted by CodeMonkey
    E. Binary? Linking? No -- #include expands one text file into another.
    Oops, I read that question to quick. It expands library files, not binary files... silly me.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    1. It's hard to say whether macros or directives come first. The standard reads as though they happen together, from the start of the file to the end.

    4. It's kind of hard to say what #import does, since it doesn't exist. (Objective-C++ uses it, and there it it's more-or-less #include with guards built in; any file that is #imported is only ever included once, no matter how often it appears in the file.)

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by tabstop View Post
    1. It's hard to say whether macros or directives come first. The standard reads as though they happen together, from the start of the file to the end.
    I would say they are processed before macros (i.e. #define's) are expanded, otherwise stuff like this wouldn't work:
    Code:
    #ifdef WIN32
    #  define PATH_SEPARATOR  \\
    #else
    #  define PATH_SEPARATOR  /
    #endif
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by cpjust View Post
    I would say they are processed before macros (i.e. #define's) are expanded, otherwise stuff like this wouldn't work:
    Code:
    #ifdef WIN32
    #  define PATH_SEPARATOR  \\
    #else
    #  define PATH_SEPARATOR  /
    #endif
    If they were processed before macros are expanded, then the preprocessor directives wouldn't know which condition to follow, since the condition is in this and most cases a macro.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, yes, but (1) #define is a preprocessor directive, and (2) order still matters -- if WIN32 is defined after that piece of code, PATH_SEPARATOR will still be /. Think of how WIN_LEAN_AND_MEAN has to be defined before you include <windows.h>, or how NDEBUG has to be defined before <assert.h> if you want to disable assertions.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Statement A is incorrect (and, in fact, meaningless). Preprocessor directives and macro expansions are processed sequentially from beginning to end of a compilation unit. So processing of preprocessor directives can be interleaved with macro expansions.

    Statement B is ambiguous. It is possible to nest #if/#elif/#else directives. The wording of the question does not exclude nesting. If nesting is not excluded, the statement is correct. Otherwise, the statement is incorrect.

    Statement C is ambiguous. The #pragma directive itself is machine independent. However, the results of using particular pragmas are compiler dependent. There are no standard pragmas.

    Statement D is incorrect. #import is not a standard preprocessor directive. It is a non-standard extension supported by some compilers.

    Statement E is incorrect. The preprocessor replaces the #include directive with the text of the specified file. It has nothing to do with identifying binary files to be linked to the program.
    Last edited by grumpy; 01-11-2009 at 12:56 AM.

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by tabstop View Post
    Well, yes, but (1) #define is a preprocessor directive, and (2) order still matters -- if WIN32 is defined after that piece of code, PATH_SEPARATOR will still be /. Think of how WIN_LEAN_AND_MEAN has to be defined before you include <windows.h>, or how NDEBUG has to be defined before <assert.h> if you want to disable assertions.
    Sure, if you put it that way then #1 is false. I was thinking about it in a smaller scope, such as one #if/#endif block, where other macros were already expanded above it...
    I'd have to agree that the questions are very badly worded and ambiguous.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    A) Incorrect. This happens at the same time. In particular, it is implementation-specific whether macros in an #error directive are expanded, if I remember correctly. However, you cannot form preprocessor directives by expanding macros (except the C99 _Pragma preprocessor keyword), so this may be what the web quiz wants to know.

    B) What grumpy said. There can be only one #else associated with an #if (but any number of #elifs), but lexically there can be as many #elses between an #if and its #endif as the compiler allows to nest.

    C) What grumpy said.

    D) There is no #import directive in the standard. Objective-C (and Objective-C++) use #import as a sort of guarded #include, and GCC makes this available to C and C++ programs as well, I think. The MS compiler uses #import as basically, "generate a header file from this COM type library and include it". It's also used to reference .Net assemblies in C++/CLI.

    E) Just plain wrong. What grumpy said.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Horrible question/answer selection, but the answer is obviously A simply by the wording (it describes preprocessor directives correct or not, while the other choices are feature statements - and all incorrect anyway). Unless the author incredibly misunderstood an intro tutorial (since they usually start with #include) and it's E.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  12. #12
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Unless there's an option for "None of the above", I would choose A since it could be correct depending on how you interpret the question, the other answers are all 100% wrong.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

Popular pages Recent additions subscribe to a feed