1

I have a problem with the following code

template<typename... TArgs>
void SomeFunc() {
   Foo* data[] = {
     Func<TArgs>()..., // <- expand the pack into array but calling Func for each type
     nullptr
   };
}

Func of course returns Foo* instance.

The nullptr at the end is for the case if TArgs is empty so that the array has size is never zero but despite this fact when compiling the code and instantiating SomeFunc with empty template argument list I get:

cannot allocate an array of constant size 0

like the nullptr element was never there. If I change the declaration of the array to:

Foo* data[sizeof...(TArgs) + 1] = 

The error message changes too:

Error   2   error C4789: buffer 'data' of size 8 bytes will be overrun; -4 bytes will be written starting at offset 8

What am I missing ? If someone could please enlighten me because I am clearly hammering this problem for too long and probably don't see the main issue here.

8
  • Works fine here with GCC and I don't see any problem with the code. Probably a VC++ bug? What happens when you replace nullptr with (Foo*)0? Commented Oct 20, 2013 at 16:45
  • The same, cannot allocate array of size 0... argh I have a strong urge to punch someone from VC++ team in the face if this is a bug in the compiler... wasted so much time on this Commented Oct 20, 2013 at 16:48
  • Next attempt to fix it: Add Foo* NullFoo(){return nullptr;} and replace nullptr in your code with NullFoo(). Commented Oct 20, 2013 at 16:50
  • I would say it's a bug, but punching anybody in the face is probably unwarranted -- it's already been fixed (2013 RTM compiles it just fine). Commented Oct 20, 2013 at 16:50
  • Well I have no 'privilege' to work with VC2013 yet, @DanielFrey, unfortunatelly it has no effect Commented Oct 20, 2013 at 16:51

1 Answer 1

2

Just another attempt to find a work-around (too long for a comment, so I'll just post it as an answer):

struct FooNull {};

template<typename T> Foo* FuncWrapper() { return Func<T>(); }
template<> Foo* FuncWrapper< FooNull >() { return nullptr; }

template<typename... TArgs>
void SomeFuncImpl() {
    Foo* data[] = {
        FuncWrapper<TArgs>()...
    };
}

template<typename... TArgs>
void SomeFunc() {
    SomeFuncImpl<TArgs...,FooNull>();
}
Sign up to request clarification or add additional context in comments.

3 Comments

Well I came back to tell you that actually your code compiles so I consider this as an answer, but You're a little bit too late anyways as I found another workaround to the problem ;) Thanks anyway
Can you comment on what your revised solution was? I am still running into this bug as of MSVC 2013 update 5... :(
@WenzelJakob FWIW, it looks similar to this bug in a project of mine. It seems that 1) the warning only occurs in Debug mode, 2) it is bogus (unless the compiler would do something extremly stupid but no one reported any real problems) and finally 3) the problem might be fixed with the newest version of VS2015.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.