error: invalid use of incomplete type

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mahmoodn
    New Member
    • May 2009
    • 77

    error: invalid use of incomplete type

    Hi, I have a problem with a compiler error "invalid use of incomplete type". Here is the description:
    in "first.h", I have:
    Code:
    class cache_t {
    public:
    	  virtual void printStats( pseq_t *pseq );
    ...
    };
    
    class generic_cache_block_t {
    ...
    };
    in "first.C", I have:
    Code:
    template class generic_cache_template<generic_cache_block_t>;
    ...
    void cache_t::printStats( pseq_t *pseq )
    {
    	....
    }

    in "second.H", I have:
    Code:
    generic_cache_template<generic_cache_block_t> *l2_cache;
    ....
    and in "second.C", I have:
    Code:
    l2_cache->printStats( this );	[B]//error[/B]
    at the last line I get an error that
    error: invalid use of incomplete type ‘struct generic_cache_t emplate<generic _cache_block_t> ’

    I have searched about this error and some say it is occurred because of something called forward deceleration (a function is called but the
    class has not been instantiated yet). I doubt about existence of such issue. Any idea is appreciated.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    I see no definition of generic_cache_t emplate<> in your code, only a forward declaration line 1 of first.C

    A forward declaration has this form

    class <ClassName>;

    It tells the compiler that a class with this name exists and may be defined at a later time. From this information the compiler can create pointers and references to the class but the compiler can not use any members of the class because they have not yet been declared in a class definition.

    I think you have failed to post some of the relevent code.

    Comment

    • mahmoodn
      New Member
      • May 2009
      • 77

      #3
      Sorry, At the end of "first.h" right after the generic_cache_b lock_t class, I have:
      Code:
      template <class BlockType>
      class generic_cache_template : public cache_t {
      public:
          ....
      protected:
          ...
      };
      I see no "class <ClassName>;" definition. So as you said, this is the source of error. "generic_cache_ template" is dependent on "cache_t" but "cache_t" is not instantiated yet. Am I right?

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        No, this is not about instantiation but about definition of the types. Instantiation creates an object of a type but this is about the use of the types and how the types are defined and declared. If

        Code:
        template <class BlockType>
        class generic_cache_template : public cache_t {
            ....
        };
        Appears at the end of first.h then generic_cache_t emplate is defined in the presence of the definition of cache_t, which it would have to be.

        The problem is in second.C so the question is what does second.C #include and in what order and possibly what do the #included files #include.

        Comment

        • mahmoodn
          New Member
          • May 2009
          • 77

          #5
          I have not written this code however I want to use it under gcc 4.4.1. After searching for definitions I found a third file (!) called "third.h" and it contains all of the forward decelerations:
          Code:
          /*------------------------------------------------------------------------*/
          /* Forward class declaration(s)                                           */
          /*------------------------------------------------------------------------*/
          class cache_t;
          class generic_cache_block_t;
          template <class BlockType> class generic_cache_template;
          ...
          Now in the body of "first.C" I have (in order):
          Code:
          #include "third.h"
          #include "first.h"
          ...
          In the body of "second.C" I have (in order):
          Code:
          #include "third.h"
          #include "second.h"
          ...
          Sorry if I forgot lots of things...

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            And that explains the problem, second.C is using generic_cache_t emplate<generic _cache_block_t> through l2_cache but it only includes thrid.H and second.H.

            thrid.H forward declares generic_cache_t emplate<generic _cache_block_t> and second.H uses that forward declaration to declare the pointer l2_cache.

            All well and good but second.C trys to access members of l2_cache requiring a full definition of generic_cache_t emplate<generic _cache_block_t> but that definition is in first.H which is not included in second.C


            Try include first.H into second.C (if you haven't already).

            Don't worry too much but not including everything first time, when you don't quite understand why a problem it happening it is very hard to know what is and isn't relevant.

            Comment

            • mahmoodn
              New Member
              • May 2009
              • 77

              #7
              No that didn't help. I found that member functions for generic_cache_t emplate were moved from first.C to first.h. I then put them back to first.C and now all things are well. I don't know why they move the definitions from .C to .h.
              I still doubt if that was the real source of problem (maybe I mistakenly change something) because he error I got was related to forward declerations and we were redirected to that direction.

              Thank you very much indeed for your helps and clue. Without your help I was not able to track the error. :)

              Comment

              • sridhard2406
                New Member
                • Dec 2007
                • 52

                #8
                At any cost. .h file should have only declaration, it should not have definition, In Second.h file, you trying to create the instance of the pointer object.

                Comment

                • Banfa
                  Recognized Expert Expert
                  • Feb 2006
                  • 9067

                  #9
                  Not true for a template sridhard2406, all the definitions for a templated class or function need to be in the header file because it is a template for a class (or function), the compiler creates the actual class (or function) when it sees it in use. If a particular function in a templated class in not in the header then when that function gets used the template for the function is unavailable and the compiler can not create the actual function resulting in an unresolved external.

                  Comment

                  Working...