How two check struct size at compile time

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

    How two check struct size at compile time

    On a file A.c I define the structure T1
    typedef struct {
    int dummy;
    int age;
    char lastname [128];
    char firstname[128];
    } T1_user;


    On a file B.c I define a strcuture T2

    typedef struct {
    int id;
    int age;
    char dummy[256]
    } T2_id;

    I would like to generate an error during compilation if sizeof (T1)
    differ from sizeof(T2).
    I tried
    #if sizeof(T2_id) != sizeof(T1_user)
    #error "Size of T1_user differ from T2_id, compile abort!"
    #endif


    But it fails on metrowerks as on GCC.

    This is a sample, in real T1 from Tn are unions and I would like to
    guaranty that interprocess exchange can't lead to buffer overflow if one
    Tn type is modified in the future.

    Regards,

    - François -
  • S.Tobias

    #2
    Re: How two check struct size at compile time

    FTSoJ <FTSoJ@ftsoj.or g> wrote:
    [color=blue]
    > #if sizeof(T2_id) != sizeof(T1_user)
    > #error "Size of T1_user differ from T2_id, compile abort!"
    > #endif[/color]

    Preprocessor will not do it, you have to trick the compiler
    to do it for you.
    Google for "CCASSERT", a handy invention in this group.

    --
    Stan Tobias
    mailx `echo siXtY@FamOuS.Be dBuG.pAlS.INVALID | sed s/[[:upper:]]//g`

    Comment

    • Christian Bau

      #3
      Re: How two check struct size at compile time

      In article <428d750b$0$116 84$8fcfb975@new s.wanadoo.fr>,
      FTSoJ <FTSoJ@FTSoJ.OR G> wrote:
      [color=blue]
      > On a file A.c I define the structure T1
      > typedef struct {
      > int dummy;
      > int age;
      > char lastname [128];
      > char firstname[128];
      > } T1_user;
      >
      >
      > On a file B.c I define a strcuture T2
      >
      > typedef struct {
      > int id;
      > int age;
      > char dummy[256]
      > } T2_id;
      >
      > I would like to generate an error during compilation if sizeof (T1)
      > differ from sizeof(T2).
      > I tried
      > #if sizeof(T2_id) != sizeof(T1_user)
      > #error "Size of T1_user differ from T2_id, compile abort!"
      > #endif[/color]

      Try these two:

      char* p = 0;
      char* q = 1;

      One compiles, the other doesn't. The reason is that 0 is a "null pointer
      constant" and will be converted to a null pointer when needed, 1 isn't
      and assigning an int to a char* is not allowed.

      Say you want to verify at compile time that sizeof (T2_id) == sizeof
      (T1_user). The expression

      sizeof (T2_id) != sizeof (T1_user)

      is 0 if the sizes are the same, and 1 if the sizes are different.
      Therefore

      char* p = (sizeof (T2_id) != sizeof (T1_user));

      will compile if the sizes are the same and won't compile if the sizes
      are different. Now pack that into a nice macro for readability, and
      that's it.

      Comment

      • jacob navia

        #4
        Re: How two check struct size at compile time

        Christian Bau wrote:[color=blue]
        > In article <428d750b$0$116 84$8fcfb975@new s.wanadoo.fr>,
        > FTSoJ <FTSoJ@FTSoJ.OR G> wrote:
        >
        >[color=green]
        >>On a file A.c I define the structure T1
        >>typedef struct {
        >> int dummy;
        >> int age;
        >> char lastname [128];
        >> char firstname[128];
        >>} T1_user;
        >>
        >>
        >>On a file B.c I define a strcuture T2
        >>
        >>typedef struct {
        >> int id;
        >> int age;
        >> char dummy[256]
        >>} T2_id;
        >>
        >>I would like to generate an error during compilation if sizeof (T1)
        >>differ from sizeof(T2).
        >>I tried
        >>#if sizeof(T2_id) != sizeof(T1_user)
        >>#error "Size of T1_user differ from T2_id, compile abort!"
        >>#endif[/color]
        >
        >
        > Try these two:
        >
        > char* p = 0;
        > char* q = 1;
        >
        > One compiles, the other doesn't. The reason is that 0 is a "null pointer
        > constant" and will be converted to a null pointer when needed, 1 isn't
        > and assigning an int to a char* is not allowed.
        >
        > Say you want to verify at compile time that sizeof (T2_id) == sizeof
        > (T1_user). The expression
        >
        > sizeof (T2_id) != sizeof (T1_user)
        >
        > is 0 if the sizes are the same, and 1 if the sizes are different.
        > Therefore
        >
        > char* p = (sizeof (T2_id) != sizeof (T1_user));
        >
        > will compile if the sizes are the same and won't compile if the sizes
        > are different. Now pack that into a nice macro for readability, and
        > that's it.[/color]

        VERY clever. Neever thought about it!

        Comment

        • Alex Fraser

          #5
          Re: How two check struct size at compile time

          "FTSoJ" <FTSoJ@FTSoJ.OR G> wrote in message
          news:428d750b$0 $11684$8fcfb975 @news.wanadoo.f r...
          [snip][color=blue]
          > I would like to generate an error during compilation if sizeof (T1)
          > differ from sizeof(T2).
          > I tried
          > #if sizeof(T2_id) != sizeof(T1_user)
          > #error "Size of T1_user differ from T2_id, compile abort!"
          > #endif
          >
          > But it fails on metrowerks as on GCC.
          >
          > This is a sample, in real T1 from Tn are unions and I would like to
          > guaranty that interprocess exchange can't lead to buffer overflow if one
          > Tn type is modified in the future.[/color]

          Instead of trying to ensure they are all the same size, perhaps you could
          make the code insensitive to different sizes - for example, by putting them
          all in a union and using that as the unit for "interproce ss exchange".

          Alex


          Comment

          • Jason Curl

            #6
            Re: How two check struct size at compile time

            FTSoJ wrote:[color=blue]
            > On a file A.c I define the structure T1
            > typedef struct {
            > int dummy;
            > int age;
            > char lastname [128];
            > char firstname[128];
            > } T1_user;
            >
            >
            > On a file B.c I define a strcuture T2
            >
            > typedef struct {
            > int id;
            > int age;
            > char dummy[256]
            > } T2_id;
            >
            > I would like to generate an error during compilation if sizeof (T1)
            > differ from sizeof(T2).
            > I tried
            > #if sizeof(T2_id) != sizeof(T1_user)
            > #error "Size of T1_user differ from T2_id, compile abort!"
            > #endif
            >
            >
            > But it fails on metrowerks as on GCC.
            >
            > This is a sample, in real T1 from Tn are unions and I would like to
            > guaranty that interprocess exchange can't lead to buffer overflow if one
            > Tn type is modified in the future.[/color]

            The only solutions I've seen in API's is to pass the length of the
            structure at the beginning of the structure, and use run-time checking
            to protect against overflows.
            [color=blue]
            >
            > Regards,
            >
            > - François -[/color]

            Comment

            • Old Wolf

              #7
              Re: How two check struct size at compile time

              Christian Bau wrote:[color=blue][color=green]
              > >
              > > I would like to generate an error during compilation if
              > > sizeof (T1) differ from sizeof(T2).[/color]
              >
              > char* p = (sizeof (T2_id) != sizeof (T1_user));
              >
              > will compile if the sizes are the same and won't compile if the
              > sizes are different. Now pack that into a nice macro for
              > readability, and that's it.[/color]

              Another of the many options is:

              typedef char p[ (sizeof(T2) == sizeof(T1)) ? 1 : -1];

              because you can't have an array type with negative bound.
              Also this option won't actually declare a variable and
              potentially use up memory, and is more likely (IME) to
              cause the compiler to stop compilation.

              If you make this a macro, you probably want to roll
              __LINE__ into it, otherwise if you use the macro twice in the
              same scope, the compiler will complain about a re-declared
              variable.

              For a pre-existing solution, check out STATIC_ASSERT in the
              preprocessor section of http://www.boost.org/

              Comment

              Working...