0
#include <iostream>

class test {
 virtual void func() = 0;
}; 

int main(){
 test t[] = {};
 return 0;
}

Above code will generate this compile time error:

error: array of abstract class type 'test'

However, it compiles if an array of pointers is used instead:

 test* t[] = {};

Is it because pure virtual functions don't have a size yet so the compiler doesn't know how much space it should allocate? but pointers do have a size so it's fine?

Dan
  • 577
  • 1
  • 3
  • 9
  • An abstract class cannot be instanciated, but you can have pointers to it. – anastaciu Aug 19 '20 at 17:30
  • I haven't instantiated `test` tho, just creating an array of it. – Dan Aug 19 '20 at 17:31
  • An array of abstract class instances wouldn't be useful for anything, for the same reason that `test t;` would not be useful. – jtbandes Aug 19 '20 at 17:32
  • 1
    When you instantiate an array, you instantiate all of the elements of the array. If you can't instantiate the elements, the compiler alerts you. I see what you're doing here, empty array, but clearly the compiler does not care. It cannot make an array of `test`. – user4581301 Aug 19 '20 at 17:33
  • see https://stackoverflow.com/questions/274626/what-is-object-slicing – Alan Birtles Aug 19 '20 at 17:33
  • 1
    @Dan, `test t[] = {};` wouldn't compile even if it wasn't an abstract class because a size must be provided, and if it is, let's say `test t[5] = {};`, the compiler will call the constructors of this class for each element of the declared array, since it's an abstact class it cannot do it. – anastaciu Aug 19 '20 at 17:36
  • I think you're being fooled by a compiler that allows arrays more leeway than the C++ Standard does. Once you go non-Standard, you need to consult the compiler documentation to find out what the behaviour is. – user4581301 Aug 19 '20 at 17:39
  • @user4581301, I stand corrected, gcc let's you compile an empty array, for some reason, but not of abstact objects, obvioulsy. – anastaciu Aug 19 '20 at 17:45
  • 1
    @anastaciu I wasn't correcting you. Your interpretation is correct. I meant the comment as a warning to the asker about compiler extensions requiring their own documentation. – user4581301 Aug 19 '20 at 17:48
  • 1
    @user4581301, Yes I know, I pinged you to see if you know why this happens, it gets even wierder, if I use `-pedantic`, not `-pedantic-errors` mind you, it then fails to compile with the expected `error: zero-size array ‘t’`. – anastaciu Aug 19 '20 at 17:50
  • That said, I guess the warning should be more along the lines of compilers CAN be extended, so watch out! That behaviour you're exploiting might be different or not exist if you change compilers or even compiler versions. – user4581301 Aug 19 '20 at 17:50
  • 1
    My suspicion is g++ allows this to because of C's [flexible array members](https://en.wikipedia.org/wiki/Flexible_array_member). – user4581301 Aug 19 '20 at 17:51

1 Answers1

4

Is it because ...

It is because abstract classes cannot be instantiated and as such, there cannot be arrays of such types. It is simply not allowed in the language.

Pointers are not abstract classes (nor are they even classes) regardless of the type that they point at.

test* t[] = {}; is however ill-formed regardless because an array variable cannot have zero elements.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • so if they are pointers then the compiler will not call the constructors as they are just pointers? – Dan Aug 19 '20 at 17:37
  • @Dan Yes. Pointers don't have constructors. – eerorika Aug 19 '20 at 17:39
  • I just did `int t[] = {};` and it compiles fine. – Dan Aug 19 '20 at 17:40
  • @Dan Regardless, it is ill-formed. If the compiler does not diagnose it, then the compiler does not conform to the C++ standard. And other, standard conforming compilers, are allowed to not compile it fine. – eerorika Aug 19 '20 at 17:40
  • @Dan You will have to check documentation for your compiler to find out what the compiler expects and how it will behave. I know g++'s array extensions leads to many interesting differences. For example, `int arr[n] = {0};`, where `n` is a variable, has tripped up many because it doesn't zero-initialize the entire array. – user4581301 Aug 19 '20 at 17:45