- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following code fails to compile with diagnostic message
test.cpp
test.cpp(13): error: incomplete type is not allowed
T items[T_NUMITEMS];
^
detected during instantiation of class TypeAllocator [with T=Foo, T_NUMITEMS=64U]" at line 81
test.cpp(13): error: incomplete type is not allowed
T items[T_NUMITEMS];
^
detected during instantiation of class TypeAllocator
What am I doing wrong and why compiler thinks that Foo class is incomplete type?
Compiler version 11.1 build 20090930
[cpp]#include#include #define FOO_PAGE_SIZE 64 template class TypeAllocator { protected: typedef struct _s_typeblk { struct _s_typeblk *next; T items[T_NUMITEMS]; } _TypeBlock; protected: _TypeBlock *_head; T *_free; protected: T *setupFreeChain(_TypeBlock *blk) { int i; for(i=T_NUMITEMS-1; i>0; --i) *reinterpret_cast (&blk->items[i-1]) = &blk->items; *reinterpret_cast (&blk->items[T_NUMITEMS-1]) = NULL; return blk->items; } public: TypeAllocator(): _head(0), _free(0) { } ~TypeAllocator() { _TypeBlock *temp; while(_head) { temp = _head; _head = _head->next; ::free(temp); } } T *alloc() { _TypeBlock *nb; T *item; if(!_free) { if((nb = (_TypeBlock *)::malloc(sizeof(_TypeBlock)))==NULL) return NULL; nb->next = _head; _head = nb; _free = setupFreeChain(nb); } item = _free; _free = *reinterpret_cast (_free); return item; } void free(T *ptr) { _TypeBlock *blk; for(blk=_head; blk; blk=blk->next) if(ptr >= blk->items && ptr <= &blk->items[T_NUMITEMS-1]) break; if(blk) { *reinterpret_cast (ptr) = _free; _free = ptr; } } }; class Foo { protected: static TypeAllocator allocator; public: void *operator new(size_t cb) { return (void *)allocator.alloc(); } void operator delete(void *ptr, size_t cb) { allocator.free((Foo *)ptr); } }; TypeAllocator Foo::allocator; int main() { Foo *foo = new Foo(); delete foo; } [/cpp]
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for attaching a testcase.
It seems a compiler bug to me. VC2008 compiles fine. I'll file a bug report to the compiler engineer team and will let you know if there's a work-around or any progress.
Thanks again!
Jennifer
It seems a compiler bug to me. VC2008 compiles fine. I'll file a bug report to the compiler engineer team and will let you know if there's a work-around or any progress.
Thanks again!
Jennifer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Our engineer found a work-around for this case.
Please move the struct-type to the outside of the class template like following:
Our engineer found a work-around for this case.
Please move the struct-type to the outside of the class template like following:
[cpp]#include#include #define FOO_PAGE_SIZE 64 template struct _s_typeblk { struct _s_typeblk *next; M items[M_SIZE]; }; template class TypeAllocator { protected: typedef _s_typeblk _TypeBlock; protected: _TypeBlock *_head; T *_free; protected: T *setupFreeChain(_TypeBlock *blk) { int i; for(i=T_NUMITEMS-1; i>0; --i) *reinterpret_cast (&blk->items[i-1]) = &blk->items; *reinterpret_cast (&blk->items[T_NUMITEMS-1]) = NULL; return blk->items; } public: TypeAllocator(): _head(0), _free(0) { } ~TypeAllocator() { _TypeBlock *temp; while(_head) { temp = _head; _head = _head->next; ::free(temp); } } T *alloc() { _TypeBlock *nb; T *item; if(!_free) { if((nb = (_TypeBlock *)::malloc(sizeof(_TypeBlock)))==NULL) return NULL; nb->next = _head; _head = nb; _free = setupFreeChain(nb); } item = _free; _free = *reinterpret_cast (_free); return item; } void free(T *ptr) { _TypeBlock *blk; for(blk=_head; blk; blk=blk->next) if(ptr >= blk->items && ptr <= &blk->items[T_NUMITEMS-1]) break; if(blk) { *reinterpret_cast (ptr) = _free; _free = ptr; } } }; class Foo { protected: static TypeAllocator allocator; public: void *operator new(size_t cb) { return (void *)allocator.alloc(); } void operator delete(void *ptr, size_t cb) { allocator.free((Foo *)ptr); } }; TypeAllocator Foo::allocator; int main() { Foo *foo = new Foo(); delete foo; } [/cpp]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much! It works as intended now.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page