When using a const struct field in an inialization I get an error

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Adrian20XX
    New Member
    • Feb 2008
    • 11

    When using a const struct field in an inialization I get an error

    Hi,

    Hi, I have a typedefed struct, and later when I declare multiple const structures and want to use a field of one in an inialization, I get the following error: "error C2099: initializer is not a constant".

    typedef struct {
    int Start;
    int attribute;
    } MyStructure ;

    #define FIRST 1

    const MyStructure STRUCT0={FIRST, 0} ;
    const MyStructure STRUCT1={STRUCT 0.Start+5, 25} ;
    const MyStructure STRUCT2={STRUCT 1.Start+35, 175} ;

    Any idea about to solve this? It's a c program, and I'm compiling it under Visual Studio 2008.

    I don't want to remove the "#define" because it allows me to change multiple structures at once and is more clear conceptually (actuall sometimes FIRST can be a different number), and also I don't want to use the definition in the second, third and following structs declarations because I have multiple defines that are used, and the expressions will become huge as I have more than 20 of this types of structs.

    TIA & Regards ...
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Compiles and links using Visual Studio.NET 2005.

    [code=cpp]
    #include "stdafx.h"
    typedef struct {
    int Start;
    int attribute;
    } MyStructure ;

    #define FIRST 1

    const MyStructure STRUCT0={FIRST, 0} ;
    const MyStructure STRUCT1={STRUCT 0.Start+5, 25} ;
    const MyStructure STRUCT2={STRUCT 1.Start+35, 175} ;
    int main()
    {

    }
    [/code]

    Comment

    • Adrian20XX
      New Member
      • Feb 2008
      • 11

      #3
      Originally posted by weaknessforcats
      Compiles and links using Visual Studio.NET 2005.

      [code=cpp]
      #include "stdafx.h"
      typedef struct {
      int Start;
      int attribute;
      } MyStructure ;

      #define FIRST 1

      const MyStructure STRUCT0={FIRST, 0} ;
      const MyStructure STRUCT1={STRUCT 0.Start+5, 25} ;
      const MyStructure STRUCT2={STRUCT 1.Start+35, 175} ;
      int main()
      {

      }
      [/code]
      It also compiles as a cpp file under Visual Studio 2008, but as my whole program is a C program, I didn't wanted it to be restricted to be a C++ program (i.e. to not compile under a pure C compiler).

      So, any aditional idea?

      TIA & regards ...

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        Then you have to write C.

        C++ is not C so C++ code often does not translate to C. Also, some C syntax and rules are C++ compile errors. You can't have it both ways.

        However, the C solution is:
        [code=c]
        typedef struct {
        int Start;
        int attribute;
        } MyStructure ;

        #define FIRST 1



        int main()
        {
        const MyStructure STRUCT0={FIRST, 0} ;
        const MyStructure STRUCT1={STRUCT 0.Start+5, 25} ;
        const MyStructure STRUCT2={STRUCT 1.Start+35, 175} ;

        }
        [/code]

        You have to initialize your struct variables inside main().

        Doing it outside of main() requires a constructor, which is not present in C. Since you don't have a constructor, the compiler provides one that initializes each member of the struct using the values between the braces. If you change your struct to a class and make the members public, it will still compile in C++.

        Comment

        • Adrian20XX
          New Member
          • Feb 2008
          • 11

          #5
          Originally posted by weaknessforcats
          Then you have to write C.

          C++ is not C so C++ code often does not translate to C. Also, some C syntax and rules are C++ compile errors. You can't have it both ways.

          However, the C solution is:
          [code=c]
          typedef struct {
          int Start;
          int attribute;
          } MyStructure ;

          #define FIRST 1



          int main()
          {
          const MyStructure STRUCT0={FIRST, 0} ;
          const MyStructure STRUCT1={STRUCT 0.Start+5, 25} ;
          const MyStructure STRUCT2={STRUCT 1.Start+35, 175} ;

          }
          [/code]

          You have to initialize your struct variables inside main().

          Doing it outside of main() requires a constructor, which is not present in C. Since you don't have a constructor, the compiler provides one that initializes each member of the struct using the values between the braces. If you change your struct to a class and make the members public, it will still compile in C++.
          Thanks for the suggestions weaknessforcats , this has two problems also, but also gave me an idea.

          One of the problems is that these constants are used everywhere, so they either have to have global visibility or be passed everywhere as a parameter. And the second one is that I also have to super-optimize my program for speed, so passing them as a parameter is a negative, and also the fact that they have to be initialized dinamically and so these prevents a lot of constants calculations that is made with them to be done in the compilation.

          I can try to declare them as global variables (not constants), and see how much is the performance hit I get.

          For now I'm using (and perhaps abusing) of the ## operator, and have tons of constants like this:
          const MyStructure STRUCT0={FIRST, 0} ;
          const MyStructure STRUCT1={STRUCT 0.Start+5, 25} ;
          const MyStructure STRUCT2={STRUCT 1.Start+35, 175} ;

          #define STRUCT0_START FIRST
          #define STRUCT0_ATTRIBU TE 0
          #define STRUCT1_START (STRUCT0_START+ 5)
          #define STRUCT1_ATTRIBU TE 25
          #define STRUCT2_START (STRUCT1_START+ 35)
          #define STRUCT2_ATTRIBU TE 175

          And then I access them by:
          #define MyStructGetStar t(number) STRUCT##number# #_START
          #define MyStructGetAttr ibute(number) STRUCT##number# #_ATTRIBUTE

          I'll see if I can come with something better, any additional idea is appreciated.

          TIA & Regards ...

          Comment

          Working...