Pre-processor peculiarities

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mamluk Caliph

    Pre-processor peculiarities

    I have an issue which I don't seem to be able to solve, and which has
    haunted me from time to time for years. Solution to either of the
    points below would help me immensely (the compiler I have is a plain C-
    compiler without C++):

    * Is there any way to determine is a 'typedef' is defined during
    compile time without depending on if a corresponding HAS_xxx_t (or
    something similar) has been defined with #define?

    * Is there any way to #define something inside a macro? For example,
    the following works:

    #define DEF_STRUCT( NAME, STRUCTURE ) \
    typedef struct{ \
    STRUCTURE \
    }frame_##NAME## _t;

    From within the code I can then define the structure like this:

    DEF_STRUCT( MY_FRAME,
    int32_t foo:24;
    int32_t bar:24;
    );

    However if I add an extra line last in the macro defining if the
    structure is existent or not, the compiler complains:

    #define DEF_STRUCT( NAME, STRUCTURE ) \
    typedef struct{ \
    STRUCTURE \
    }frame_##NAME## _t; \
    #define HAS_##NAME


    * Is there any way of defining something that when combined with the
    sizeof operator would result in 0?

    Defining an empty structure apparently isn't legal and can't be used
    as a type resulting in a zero size.


    Many thanks
    /Michael
  • Eric Sosman

    #2
    Re: Pre-processor peculiarities

    Mamluk Caliph wrote:
    I have an issue which I don't seem to be able to solve, and which has
    haunted me from time to time for years. Solution to either of the
    points below would help me immensely (the compiler I have is a plain C-
    compiler without C++):
    >
    * Is there any way to determine is a 'typedef' is defined during
    compile time without depending on if a corresponding HAS_xxx_t (or
    something similar) has been defined with #define?
    No. The preprocessor makes its decisions before the
    compiler recognizes and processes type declarations. When
    the preprocessor operates, even things like `int' and `for'
    do not yet have any special significance.
    * Is there any way to #define something inside a macro? For example,
    the following works:
    >
    #define DEF_STRUCT( NAME, STRUCTURE ) \
    typedef struct{ \
    STRUCTURE \
    }frame_##NAME## _t;
    >
    From within the code I can then define the structure like this:
    >
    DEF_STRUCT( MY_FRAME,
    int32_t foo:24;
    int32_t bar:24;
    );
    Ugh. "Beauty is in the eye of the beholder," but Ugh
    nonetheless. Also, you'll get into trouble if anybody ever
    tries something like

    DEF_STRUCT( MY_FRAME,
    int a, b, c;
    };
    However if I add an extra line last in the macro defining if the
    structure is existent or not, the compiler complains:
    >
    #define DEF_STRUCT( NAME, STRUCTURE ) \
    typedef struct{ \
    STRUCTURE \
    }frame_##NAME## _t; \
    #define HAS_##NAME
    This will not work and cannot be made to work. Even if a
    macro expands to something that looks like a preprocessor
    directive, the expansion is not processed as a directive.
    * Is there any way of defining something that when combined with the
    sizeof operator would result in 0?
    >
    Defining an empty structure apparently isn't legal and can't be used
    as a type resulting in a zero size.
    If by "combined with" you mean "used as the operand of,"
    the answer is No. Every C type either has a size of at least
    one byte, or has no size at all (which is not the same thing
    as having a size of zero bytes).

    What problem are you trying to solve by using a zero-sized
    type?

    --
    Eric Sosman
    esosman@ieee-dot-org.invalid

    Comment

    • Mamluk Caliph

      #3
      Re: Pre-processor peculiarities

      This will not work and cannot be made to work. Even if a
      macro expands to something that looks like a preprocessor
      directive, the expansion is not processed as a directive.
      >
      Would this them mean that no processor directive is ever legal inside
      a macro (i.e. anything with a number sign not meant for
      stringification of concatenation)?

      If by "combined with" you mean "used as the operand of,"
      the answer is No. Every C type either has a size of at least
      one byte, or has no size at all (which is not the same thing
      as having a size of zero bytes).
      Yes, as in "used as the operand of". How can you define something as
      having no size? I'm thinking of something like the following perhaps
      could be used to solve my problem:

      if (sizeof(nosize_ t) == 0)
      fo();
      >
      What problem are you trying to solve by using a zero-sized
      type?

      I'm trying to re-use a macro looking like this:

      #define MSG_INIT( VAR , CMD) \
      DEF_MSG_SIMPLE( VAR ,HEADERID_##CMD , sizeof(frame_## CMD##_t) )

      This is used for initializing a message header in a field-bus based
      system with many hundred unique ID.s. The problem is that sometimes
      messages have no data (i.e. there exists no frame_XXX_t). The macro
      could be expanded to take the size as an argument as well, but then if
      the data format changes, one would have to search and replace in
      application code.

      Defining anything that could be usable inside the macro, but that at
      the same time wouldn't imply changes to the application code would
      work. I.e. I was thinking of defining "dummy" types for those messages
      missing data returning the size zero, but I can't figure out how.

      Regards
      /Michael











      Comment

      • Eric Sosman

        #4
        Re: Pre-processor peculiarities

        Mamluk Caliph wrote:
        > This will not work and cannot be made to work. Even if a
        >macro expands to something that looks like a preprocessor
        >directive, the expansion is not processed as a directive.
        >>
        >
        Would this them mean that no processor directive is ever legal inside
        a macro (i.e. anything with a number sign not meant for
        stringification of concatenation)?
        It means the macro expansion is never a preprocessor
        directive, not even if it looks like one. Off-hand, I cannot
        think of a context where a directive-like expansion would
        not be an error.
        > If by "combined with" you mean "used as the operand of,"
        >the answer is No. Every C type either has a size of at least
        >one byte, or has no size at all (which is not the same thing
        >as having a size of zero bytes).
        >
        Yes, as in "used as the operand of". How can you define something as
        having no size?
        Incomplete types, bit-fields, and functions have no size:

        struct undefined *p;
        void *q;
        struct { int b : 4; } s;
        int (*f)(double);

        n = sizeof *p; /* BZZZT! */
        n = sizeof *q; /* BZZZT! */
        n = sizeof s.b; /* BZZZT! */
        n = sizeof *f; /* BZZZT! */
        > What problem are you trying to solve by using a zero-sized
        >type?
        >
        I'm trying to re-use a macro looking like this:
        >
        #define MSG_INIT( VAR , CMD) \
        DEF_MSG_SIMPLE( VAR ,HEADERID_##CMD , sizeof(frame_## CMD##_t) )
        >
        This is used for initializing a message header in a field-bus based
        system with many hundred unique ID.s. The problem is that sometimes
        messages have no data (i.e. there exists no frame_XXX_t). The macro
        could be expanded to take the size as an argument as well, but then if
        the data format changes, one would have to search and replace in
        application code.
        >
        Defining anything that could be usable inside the macro, but that at
        the same time wouldn't imply changes to the application code would
        work. I.e. I was thinking of defining "dummy" types for those messages
        missing data returning the size zero, but I can't figure out how.
        It sounds to me like you're trying to use zero-sized types
        as a hack to compensate for the deficiencies of the macro.
        Maybe it would be better to improve the macro than to attempt
        the hack, possibly by introducing another macro for the no-data
        case. (Presumably it is known which messages have no data, or
        you wouldn't know which fake types to define.)

        --
        Eric Sosman
        esosman@ieee-dot-org.invalid

        Comment

        Working...