3 Replies Latest reply on May 17, 2018 9:07 AM by Maxim Kartashev-Oracle

    Subject: Compiler CC creates undefined symbols

    Oqelu

      Post here other cases.

      It does so in many cases. Then a linker, at the time of linking, or running, emits an error that the symbol is not defined.
      Although, optimization should remove the symbol altogether, and "inline" it instead as a literal integer.

      One such case is with members of classes, which are
      static const enum
      It does not help to specify any underlying base type, like:
      static const enum Variable : unsigned char
      Workarounds

      • Change to any other type the declaration, and cast back to enum at all places of use with other variables, of type enum. Assignment, or comparison to integers, for example, does not need the cast-back.
        Then the symbol does properly disappear indeed because of optimization, which I mentioned.
        If it is not necessary to optimize, then perhaps the symbol would appear in object file, or executable.
      • Remove static, or const.
        • 1. Re: Subject: Compiler CC creates undefined symbols
          Maxim Kartashev-Oracle

          I'm not sure if I guessed the test case correctly from the description, but I think the compiler is probably correct. Consider

          struct A
          {
              static const enum Variable { v1, v2, v3} v;
          
              A()
              {
              Variable m = v;
              }
          };
          
          int main()
          {
              A a;
          }
          

           

          When you try compiling the above example, both CC and g++ report the same (linker) error:

           

          $ CC -std=c++14 a.cc

          a.o: In function `main':

          a.cc:(.text+0xa): undefined reference to `A::v' ...

           

          $ g++ -std=c++11 a.cc

          /tmp/cccBPVFS.o: In function `A::A()':

          a.cc:(.text._ZN1AC2Ev[_ZN1AC5Ev]+0xa): undefined reference to `A::v' ...

           

          This is what the C++11 standard says on the matter ([class.static.data] p2):

          The declaration of a static data member in its class definition is not a definition [...]

           

          To get the behavior you want, you need to provide a definition for A::v after the class definition like so

          const A::Variable A::v = v1;
          

          or provide an initializer in-class, but in this case you may not ODR-use A::v (see p.3 of the same section of the standard):

              static const enum Variable { v1, v2, v3} v = v1;
          

           

          This looks like unnecessary work to many people and there have been suggestions on how to improve the situation from several C++ committee members; see, for example, the inline variables paper wg21.link/N4424.

          • 2. Re: Subject: Compiler CC creates undefined symbols
            Oqelu

            You mistook me. I did not provide an example of code. I only provided an example of type. Of course I did initialize the enum; define it, as you term it.

            The problem is not in static. The problem is in enum. When I replace it with its base type, like int, the symbol is no longer "undefined". It just disappears. Perhaps becomes a literal in object code.
            - No other change in code. This means that I do initialize it indeed. No issue with ODR, whatever you mean by that.

            enum does compile in small code. In large code it becomes an undefined symbol.
            In the other report I mentioned that large code invokes other bugs in initializer too:
            https://community.oracle.com/thread/4134581

            • 3. Re: Subject: Compiler CC creates undefined symbols
              Maxim Kartashev-Oracle

              You mistook me. I did not provide an example of code. I only provided an example of type.

               

              Sorry about that. Without seeing the actual code, I can't diagnose the problem. If you can post a snipped of the code together with the error the compiler generates, that might help us to move further.