0

I have a contrived example. I think the key point is that there is an illegal conversion into a base class. I should not be able to have an array of MyBase.

This example compiles on my computer in VS2013:

#include <vector>
#include <iostream>

struct MyBase {
    virtual size_t Count() = 0;
};

struct MyContainer : MyBase {
    size_t Count() override;
};

size_t MyContainer::Count() {
    return 4;
}

int main() {
    MyContainer countable;
    MyBase x[] = { countable };
    std::cout << x[0].Count() << std::endl;
    return 0;
}

Is this getting the same error on other compilers?

Why am I getting a linker error instead of a compiler warning? (I do get an Intellisense warning)

Note

The question is not what is happening here or how to fix it. I know that. I was wondering why it is a linker error instead of a compiler error and whether that is specific to my compiler only.

To make it clear, I know that this is a "fix":

int main() {
    MyContainer countable;
    MyBase * x[] = { &countable };
    std::cout << x[0]->Count() << std::endl;
    return 0;
}

But fixing is not the issue here. What I do not understand is why the error is not diagnosed by the compiler but instead by the linker.

Community
  • 1
  • 1
Johannes
  • 6,490
  • 10
  • 59
  • 108
  • Your issue is `MyBase x[]` would have to either be an array of references or pointers for that to work. – Cory Kramer May 17 '17 at 11:11
  • No. I understand what is happening. My question is why that is not a compiler error but a linker error instead. – Johannes May 17 '17 at 15:49
  • To help people answer your question, you'll need to be more specific about the error. Please [edit] your post to incorporate the exact errors you get from your [mcve] (preferably using copy+paste to avoid transcription errors). You might want to tag as [tag:visual-studio], too. As far as I (and GCC) can see, the declaration of `x` is in error because `Count()` is pure virtual. If I provide an implementation, then it does compile (because a `MyBase` can be constructed from a `MyContainer` by the compiler-defaulted copy constructor, i.e. object slicing) and the program correctly outputs `0`. – Toby Speight May 17 '17 at 17:27
  • 2
    The reason it's a linker error is probably because your compiler isn't diagnosing the call to `virtual MyBase::Count()`, but is devirtualizing it. Then your linker expects to find a definition for it. – Toby Speight May 17 '17 at 17:33
  • 1
    FWIW, the `MyBase x[]` gives me compile errors in both GCC and Clang, both saying that the type of `x` is not valid because the class is abstract. It's probably a bug in Microsoft's compiler. – Wyzard May 18 '17 at 03:33

0 Answers0