preprocessor question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Nathan Moinvaziri

    preprocessor question

    I am wonder if there is a way to use preprocessor definitions to
    expose code only if a particular file is included in a project. I am
    targeting the msvc.

    I am thinking of something like

    #if defined(filecab inet.h) // if filecabinet.h is part of the project

    ....

    #endif
  • Keith Thompson

    #2
    Re: preprocessor question

    Nathan Moinvaziri <nmoinvaziri@gm ail.comwrites:
    I am wonder if there is a way to use preprocessor definitions to
    expose code only if a particular file is included in a project. I am
    targeting the msvc.
    >
    I am thinking of something like
    >
    #if defined(filecab inet.h) // if filecabinet.h is part of the project
    >
    ...
    >
    #endif
    There's no general method. But if each header defines a particular
    symbol, you can use #ifdef on that symbol.

    Many headers are wrapped in header guards, something like:

    #ifndef H_NAME
    #define H_NAME
    ...
    #endif

    but I wouldn't necessarily recommend referring to that symbol outside
    the header, since it's in some sense "local" to the header itself and
    could be changed later.

    If it's a header that you don't control, you could have a problem.
    You might be able to find some macro that happens to be defined in a
    header; for example, if you're using standard headers, then INT_MAX
    will be defined only if <limits.hhas been included.

    (The language *could* have defined such a feature, but I suspect the
    need for it was so rare that it didn't occur to anyone.)

    --
    Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

    Comment

    • Robbie Hatley

      #3
      Re: preprocessor question

      Nathan Moinvaziri queried:
      I am wonder if there is a way to use preprocessor definitions to
      expose code only if a particular file is included in a project. I am
      targeting the msvc.
      There are various ways to do that sort of thing, yes.

      One way is, use a header's own "include guard" to determine whether
      it has been included (so-far, lexically) in a source file:

      Example:

      /* in header file "asdf.h": */
      #ifndef ASDF_H_ALRDY_IN CL
      #define ASDF_H_ALRDY_IN CL
      .... a bunch of struct definitions ...
      .... a bunch of function prototypes ...
      #endif

      /* in source file "yuiop.c": */
      #include "asdf.h"
      int Fred (float Ethel)
      {
      ... do some preliminary stuff ...
      #ifdef ASDF_H_ALRDY_IN CL
      ... do some stuff ...
      #else
      ... do some OTHER stuff instead...
      #endif
      ... do some final stuff ...
      return 73;
      }
      I am thinking of something like
      >
      #if defined(filecab inet.h) // if filecabinet.h is part of the project
      Firstly, lose the parentheses. Secondly, use the include guard
      rather than the file name. Thirdly, "//" isn't standard C.
      Fourthly, comments on end of #defines SHOULD be ignored by
      the preprocessor, but don't trust that; put them on the previous
      line instead.

      So I'd re-write that like so:

      /* if filecabinet.h has been included */
      #ifdef FILE_CAB_H
      .... some stuff ...
      #endif

      Another thing you can do, by the way, is switch things
      on and off by defining (or NOT defining) them in your
      compiler's settings. For most compilers this is done
      by adding a "/D" command in the "defines" section of
      a project's settings:

      /DMY_NIFTY_SWITC H /DYET_ANOTHER_CO NTROL

      That will define the following two macros throughout
      your project: MY_NIFTY_SWITCH and YET_ANOTHER_CON TROL .

      One nifty thing you can do with that is, you can make
      different projects that use the same source files but
      have different /D defines, which switch portions of code
      on and off.

      You could even turn your original question around and
      use such a switch to determine *WHETHER* to #include
      a header in a source (or header) file, like so:

      In project settings in compiler: "/DGRNHS_CRAVO"

      /* in header "greenhouse_ven ts.h": */
      #ifdef GRNHS_CRAVO
      #include "cravo_vent s.h"
      #else
      #include "regular_vents. h"
      #endif

      Or use the same concept to switch whole blocks of code in
      source files on or off:

      /* in source file "vents.c": */
      #include "greenhouse_ven ts.h"
      int vents (...some parameters...)
      {
      ... do some preliminary stuff...
      #ifdef GRNHS_CRAVO
      ... do vent stuff ...
      #else
      ... do DIFFERENT vent stuff ...
      #endif
      ... do some final stuff ...
      return 42;
      }

      I use techniques like that at work to generate different
      versions of the same program tailored to different customers'
      needs.

      --
      Cheers,
      Robbie Hatley
      lonewolf aatt well dott com
      www dott well dott com slant user slant lonewolf slant


      Comment

      • Keith Thompson

        #4
        Re: preprocessor question

        "Robbie Hatley" <lonewolf@well. comwrites:
        Nathan Moinvaziri queried:
        [...]
        >I am thinking of something like
        >>
        >#if defined(filecab inet.h) // if filecabinet.h is part of the project
        >
        Firstly, lose the parentheses. Secondly, use the include guard
        rather than the file name. Thirdly, "//" isn't standard C.
        Fourthly, comments on end of #defines SHOULD be ignored by
        the preprocessor, but don't trust that; put them on the previous
        line instead.
        First, the parentheses are optional; both
        #if defined SOMETHING
        and
        #if defined(SOMETHI NG)
        are perfectly legal.

        Second, the include guard is generally intended to be referred to only
        within the header that it guards, and it could be changed during later
        maintenance.

        Third (before jacob points it out), "//" comments are standard C as of
        the 1999 ISO standard. But they aren't supported in C90, and few
        compilers yet fully support C99 (though "//" comments are perhaps the
        most widely supported C99-specific feature).

        Fourth, I wouldn't worry about putting comments on the same line as a
        preprocessor directive. Conforming compilers have been required to
        allow this since the 1989 ANSI standard. (If you have a specific
        requirement to support pre-ANSI compilers, you'll have a lot more to
        worry about than that.)

        --
        Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
        Nokia
        "We must do something. This is something. Therefore, we must do this."
        -- Antony Jay and Jonathan Lynn, "Yes Minister"

        Comment

        Working...