abstract classes not detected by compiler

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bjorn

    abstract classes not detected by compiler

    I'm using interfaces in C++ by declaring classes with only pure virtual
    methods. If then someone wants to implement the interface they
    needs to inherit from the class. If the implementing class forgets to
    implement some method I normally get a compile error(if the class is created
    in some way of course). When using the Visual
    Studio 6 compiler however, it does not generate a compile error in this
    case:

    - I have a implementing class A that inherits from an interface class. It
    has not implemented all methods.
    - The implementing class A is declared as an array in a container class. The
    container class is created with new.

    The compiler do not generate any errors, but I will of course get a runtime
    error when a method with no implementation is called("pure function call" or
    something). If the container class declares A as a pointer(and performs new
    on it) or as a non-array variable, then the compiler generates compile
    errors, but not if it is declared as an array.

    So, my question is: is it a compiler fault, if it does not find out that an
    abstract class is created(which is the case here since all methods are not
    implemented)? Or should it be considered as normal that the compiler can not
    find out cases like this(i.e more complicated cases).

    /Bjorn





  • Karthik Kumar

    #2
    Re: abstract classes not detected by compiler

    Bjorn wrote:[color=blue]
    > I'm using interfaces in C++ by declaring classes with only pure virtual
    > methods. If then someone wants to implement the interface they
    > needs to inherit from the class. If the implementing class forgets to
    > implement some method I normally get a compile error(if the class is created
    > in some way of course). When using the Visual
    > Studio 6 compiler however, it does not generate a compile error in this
    > case:
    >
    > - I have a implementing class A that inherits from an interface class. It
    > has not implemented all methods.
    > - The implementing class A is declared as an array in a container class. The
    > container class is created with new.[/color]

    Posting some code is always better than describing the same.

    #include <cstdlib>

    class Base {
    public:
    virtual int donothing1(void ) = 0;
    virtual int donothing2(void ) = 0;
    };

    class A: public Base {
    public:
    virtual int donothing1(void ) {
    return 1;
    }

    //'donothing2' not implemented
    };

    class Container {
    private:
    A obj[100];
    };

    int main() {
    Container * contain = new Container;
    delete contain;
    return EXIT_SUCCESS;
    }


    The compiler errors out as follows -

    d:\classA.cpp(2 0): error C2259: 'A' : cannot instantiate abstract class

    [color=blue]
    >
    > The compiler do not generate any errors, but I will of course get a runtime
    > error when a method with no implementation is called("pure function call" or[/color]

    It is not possible to call a method with no implementation, unless
    there is a problem with the build process. Try cleaning the relevant
    object files and building the entire thing again.

    [color=blue]
    > something). If the container class declares A as a pointer(and performs new
    > on it)[/color]

    The compiler behavious is entirely determined by the type of the
    object you dynamically bind to a pointer to A.

    A * ptr ; // compiler is happy. you are not
    // instantiating anything here.

    ptr = new A ; // Assuming not all methods of A are implemented,
    // compiler would error out.
    [color=blue]
    > or as a non-array variable, then the compiler generates compile
    > errors, but not if it is declared as an array.
    >
    > So, my question is: is it a compiler fault,[/color]

    Post some code to understand things better.
    [color=blue]
    >if it does not find out that an
    > abstract class is created(which is the case here since all methods are not
    > implemented)? Or should it be considered as normal that the compiler can not
    > find out cases like this(i.e more complicated cases).[/color]

    A compiler can definitely find a scenario where not all methods of a
    class are implemented.

    --
    Karthik. http://akktech.blogspot.com .
    ' Remove _nospamplz from my email to mail me. '

    Comment

    • Thomas Maier-Komor

      #3
      Re: abstract classes not detected by compiler

      Bjorn schrieb:[color=blue]
      > I'm using interfaces in C++ by declaring classes with only pure virtual
      > methods. If then someone wants to implement the interface they
      > needs to inherit from the class. If the implementing class forgets to
      > implement some method I normally get a compile error(if the class is created
      > in some way of course). When using the Visual
      > Studio 6 compiler however, it does not generate a compile error in this
      > case:
      >
      > - I have a implementing class A that inherits from an interface class. It
      > has not implemented all methods.
      > - The implementing class A is declared as an array in a container class. The
      > container class is created with new.
      >
      > The compiler do not generate any errors, but I will of course get a runtime
      > error when a method with no implementation is called("pure function call" or
      > something). If the container class declares A as a pointer(and performs new
      > on it) or as a non-array variable, then the compiler generates compile
      > errors, but not if it is declared as an array.
      >
      > So, my question is: is it a compiler fault, if it does not find out that an
      > abstract class is created(which is the case here since all methods are not
      > implemented)? Or should it be considered as normal that the compiler can not
      > find out cases like this(i.e more complicated cases).
      >
      > /Bjorn
      >[/color]

      #include <list>

      struct ABC {
      virtual void x() = 0;
      };

      std::list<ABC *> mylist; // this is OK
      std::list<ABC> anotherlist; // this should generate a compile-time error

      Tom

      Comment

      • Victor Bazarov

        #4
        Re: abstract classes not detected by compiler

        Bjorn wrote:[color=blue]
        > [...]
        > So, my question is: is it a compiler fault, if it does not find out that an
        > abstract class is created[/color]

        _Created_? REALLY? Where? You claim that "the container class declares
        A ... as an array". Could you show how you do that?
        [color=blue]
        >(which is the case here since all methods are not
        > implemented)? Or should it be considered as normal that the compiler can not
        > find out cases like this(i.e more complicated cases).[/color]

        ------------------------------------ example 1 : no big deal
        struct ABC { // abstract
        virtual void foo() = 0;
        };

        struct CC : ABC { // concrete
        void foo() {}
        };

        int main() {
        ABC *pa; // a pointer to ABC object, uninitialised, unused
        }
        ------------------------------------ example 2 : still no big deal
        struct ABC { // abstract
        virtual void foo() = 0;
        };

        struct CC : ABC { // concrete
        void foo() {}
        };

        int main() {
        ABC *pa[10] = {0}; // an array of pointers to ABC, all 0, unused
        }
        ------------------------------------ example 3 : undefined behaviour
        struct ABC { // abstract
        virtual void foo() = 0;
        };

        struct CC : ABC { // concrete
        void foo() {}
        };

        int main() {
        ABC *pa; // an uninitialised pointer to ABC
        pa->foo(); // an attempt to use that uninitialised pointer - BOOM!
        }
        ------------------------------------ example 4 : undefined behaviour
        struct ABC { // abstract
        virtual void foo() = 0;
        };

        struct CC : ABC { // concrete
        void foo() {}
        };

        int main() {
        ABC *pa[10]; // an array of uninitialised pointers to ABC
        pa[0]->foo(); // an attempt to use an uninitialised pointer - BOOM!
        }
        ------------------------------------ example 5 : no big deal
        struct ABC { // abstract
        virtual void foo() = 0;
        };

        struct CC : ABC { // concrete
        void foo() {}
        };
        #include <list>
        int main() {
        std::list<ABC*> lst; // a standard list of pointers to ABC - unused
        }
        ------------------------------------
        All examples should compile fine (although I didn't check, just typed
        them in).

        As you can see, if there is no attempt to _instantiate_ the abstract
        class, it's still possible to have undefined behaviour, but not due to
        the call to the pure function.

        The C++ language prohibits _creation_ of _object_ of a class that is
        abstract. If your program doesn't create any objects, how can it have
        undefined behaviour? And if you don't create any objects in your code,
        how can the compiler know what your intentions are?

        Victor

        Comment

        • DaKoadMunky

          #5
          Re: abstract classes not detected by compiler

          >It is not possible to call a method with no implementation, unless[color=blue]
          >there is a problem with the build process[/color]

          Not necessarily true...

          struct Abstract
          {
          Abstract()
          {
          NonVirtual();
          }

          void NonVirtual()
          {
          PureVirtual();
          }

          virtual void PureVirtual()=0 ;
          };

          struct Concrete : public Abstract
          {
          void PureVirtual()
          {
          }
          };

          int main()
          {
          Concrete c;

          return 0;
          }

          Using MSVC++.NET a run-time error indicates that a pure virtual function was
          called.

          I don't know what the language standard says regarding this. I am guessing it
          is undefined behavior? Does the standard discuss attempts to invoke pure
          virtual functions directly or indirectly from a base class constructor (or
          destructor?)

          Comment

          • Oleg Polikarpotchkin

            #6
            Re: abstract classes not detected by compiler

            dakoadmunky@aol .com (DaKoadMunky) wrote in message news:<200410252 12213.05810.000 04374@mb-m27.aol.com>...[color=blue][color=green]
            > >It is not possible to call a method with no implementation, unless
            > >there is a problem with the build process[/color]
            >
            > Not necessarily true...
            >
            > struct Abstract
            > {
            > Abstract()
            > {
            > NonVirtual();
            > }
            >
            > void NonVirtual()
            > {
            > PureVirtual();
            > }
            >
            > virtual void PureVirtual()=0 ;
            > };
            >
            > struct Concrete : public Abstract
            > {
            > void PureVirtual()
            > {
            > }
            > };
            >
            > int main()
            > {
            > Concrete c;
            >
            > return 0;
            > }
            >
            > Using MSVC++.NET a run-time error indicates that a pure virtual function was
            > called.[/color]

            It's normal: "Concrete" object vtable is not yet properly constructed.
            I have seen the comments on this situation, but where it was ?...
            [color=blue]
            >
            > I don't know what the language standard says regarding this. I am guessing it
            > is undefined behavior? Does the standard discuss attempts to invoke pure
            > virtual functions directly or indirectly from a base class constructor (or
            > destructor?)[/color]

            Comment

            • Thomas Maier-Komor

              #7
              Re: abstract classes not detected by compiler

              Oleg Polikarpotchkin wrote:[color=blue]
              > dakoadmunky@aol .com (DaKoadMunky) wrote in message news:<200410252 12213.05810.000 04374@mb-m27.aol.com>...
              >[color=green][color=darkred]
              >>>It is not possible to call a method with no implementation, unless
              >>>there is a problem with the build process[/color]
              >>
              >>Not necessarily true...
              >>
              >>struct Abstract
              >>{
              >> Abstract()
              >> {
              >> NonVirtual();
              >> }
              >>
              >> void NonVirtual()
              >> {
              >> PureVirtual();
              >> }
              >>
              >> virtual void PureVirtual()=0 ;
              >>};
              >>
              >>struct Concrete : public Abstract
              >>{
              >> void PureVirtual()
              >> {
              >> }
              >>};
              >>
              >>int main()
              >>{
              >> Concrete c;
              >>
              >> return 0;
              >>}
              >>
              >>Using MSVC++.NET a run-time error indicates that a pure virtual function was
              >>called.[/color]
              >
              >
              > It's normal: "Concrete" object vtable is not yet properly constructed.
              > I have seen the comments on this situation, but where it was ?...
              >
              >[color=green]
              >>I don't know what the language standard says regarding this. I am guessing it
              >>is undefined behavior? Does the standard discuss attempts to invoke pure
              >>virtual functions directly or indirectly from a base class constructor (or
              >>destructor? )[/color][/color]

              a constructor cannot call any virtual functions. so any call to a
              virtual function will be non-virtual. In consequence calling a
              pure virtual function should be rejected by the compiler (IIRC)...

              Comment

              • Bjorn

                #8
                Re: abstract classes not detected by compiler

                Hi again,

                I provide a code example below to clarify things. The compiler version I use
                is:

                Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86

                The following compiles without error, but of course gives a run time error
                since all methods are not implemented.
                #include "stdafx.h"

                class Base {

                public:

                virtual void func1() = 0;

                virtual void func2() = 0;

                };

                class SubClassToBase : public Base {

                virtual void func1() {

                int i = 7;

                }

                };

                class Container {

                public:

                Base* getBase() {

                return b;

                }

                private:

                SubClassToBase b[1];

                };

                int main(int argc, char* argv[])

                {

                Container* c = new Container;

                c->getBase()->func2();

                // This will cause a runtime error, since

                // func2() is not impemented

                // The compiler does not generate error

                return 0;

                }

                /Bjorn



                "Karthik Kumar" <kaykaylance_no spamplz@yahoo.c om> wrote in message
                news:417d6028$1 @darkstar...[color=blue]
                > Bjorn wrote:[color=green]
                > > I'm using interfaces in C++ by declaring classes with only pure virtual
                > > methods. If then someone wants to implement the interface they
                > > needs to inherit from the class. If the implementing class forgets to
                > > implement some method I normally get a compile error(if the class is[/color][/color]
                created[color=blue][color=green]
                > > in some way of course). When using the Visual
                > > Studio 6 compiler however, it does not generate a compile error in this
                > > case:
                > >
                > > - I have a implementing class A that inherits from an interface class.[/color][/color]
                It[color=blue][color=green]
                > > has not implemented all methods.
                > > - The implementing class A is declared as an array in a container class.[/color][/color]
                The[color=blue][color=green]
                > > container class is created with new.[/color]
                >
                > Posting some code is always better than describing the same.
                >
                > #include <cstdlib>
                >
                > class Base {
                > public:
                > virtual int donothing1(void ) = 0;
                > virtual int donothing2(void ) = 0;
                > };
                >
                > class A: public Base {
                > public:
                > virtual int donothing1(void ) {
                > return 1;
                > }
                >
                > //'donothing2' not implemented
                > };
                >
                > class Container {
                > private:
                > A obj[100];
                > };
                >
                > int main() {
                > Container * contain = new Container;
                > delete contain;
                > return EXIT_SUCCESS;
                > }
                >
                >
                > The compiler errors out as follows -
                >
                > d:\classA.cpp(2 0): error C2259: 'A' : cannot instantiate abstract class
                >
                >[color=green]
                > >
                > > The compiler do not generate any errors, but I will of course get a[/color][/color]
                runtime[color=blue][color=green]
                > > error when a method with no implementation is called("pure function[/color][/color]
                call" or[color=blue]
                >
                > It is not possible to call a method with no implementation, unless
                > there is a problem with the build process. Try cleaning the relevant
                > object files and building the entire thing again.
                >
                >[color=green]
                > > something). If the container class declares A as a pointer(and performs[/color][/color]
                new[color=blue][color=green]
                > > on it)[/color]
                >
                > The compiler behavious is entirely determined by the type of the
                > object you dynamically bind to a pointer to A.
                >
                > A * ptr ; // compiler is happy. you are not
                > // instantiating anything here.
                >
                > ptr = new A ; // Assuming not all methods of A are implemented,
                > // compiler would error out.
                >[color=green]
                > > or as a non-array variable, then the compiler generates compile
                > > errors, but not if it is declared as an array.
                > >
                > > So, my question is: is it a compiler fault,[/color]
                >
                > Post some code to understand things better.
                >[color=green]
                > >if it does not find out that an
                > > abstract class is created(which is the case here since all methods are[/color][/color]
                not[color=blue][color=green]
                > > implemented)? Or should it be considered as normal that the compiler can[/color][/color]
                not[color=blue][color=green]
                > > find out cases like this(i.e more complicated cases).[/color]
                >
                > A compiler can definitely find a scenario where not all methods of a
                > class are implemented.
                >
                > --
                > Karthik. http://akktech.blogspot.com .
                > ' Remove _nospamplz from my email to mail me. '[/color]


                Comment

                • Karthik Kumar

                  #9
                  Re: abstract classes not detected by compiler

                  Bjorn wrote:[color=blue]
                  > Hi again,
                  >
                  > I provide a code example below to clarify things. The compiler version I use
                  > is:
                  >
                  > Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
                  >
                  > The following compiles without error, but of course gives a run time error
                  > since all methods are not implemented.
                  > #include "stdafx.h"
                  >
                  > class Base {
                  >
                  > public:
                  >
                  > virtual void func1() = 0;
                  >
                  > virtual void func2() = 0;
                  >
                  > };
                  >
                  > class SubClassToBase : public Base {
                  >
                  > virtual void func1() {
                  >
                  > int i = 7;
                  >
                  > }
                  >
                  > };
                  >
                  > class Container {
                  >
                  > public:
                  >
                  > Base* getBase() {
                  >
                  > return b;
                  >
                  > }
                  >
                  > private:
                  >
                  > SubClassToBase b[1];
                  >
                  > };
                  >
                  > int main(int argc, char* argv[])
                  >
                  > {
                  >
                  > Container* c = new Container;
                  >
                  > c->getBase()->func2();
                  >
                  > // This will cause a runtime error, since
                  >
                  > // func2() is not impemented
                  >
                  > // The compiler does not generate error
                  >
                  > return 0;
                  >
                  > }
                  >
                  > /Bjorn
                  >
                  >[/color]

                  Checked with the two compilers that I have access to.

                  class Base {

                  public:

                  virtual void func1() = 0;
                  virtual void func2() = 0;

                  };

                  class SubClassToBase : public Base {

                  virtual void func1() {
                  int i = 7;
                  }
                  };

                  class Container { //g++ errors out here

                  public:

                  Base* getBase() {
                  return b;
                  }

                  private:
                  SubClassToBase b[1]; // VC++ .NET 2003 errors out here.
                  };

                  int main(int argc, char* argv[]) {

                  Container* c = new Container;
                  c->getBase()->func2();

                  // This will cause a runtime error, since
                  // func2() is not impemented
                  // The compiler does not generate error

                  return 0;
                  }


                  gcc 3.4.2.

                  C:\>g++ -ansi -pedantic pure_virtual.cp p
                  pure_virtual.cp p:17: error: cannot declare field `Container::b' to be of
                  type `SubClassToBase '
                  pure_virtual.cp p:17: error: because the following virtual functions
                  are abstract:
                  pure_virtual.cp p:6: error: virtual void Base::func2()


                  VC++ .NET is not happy either.

                  C:\pure_virtual .cpp(26) : error C2259: 'SubClassToBase ' : cannot
                  instantiate abstract class
                  due to following members:
                  'void Base::func2(voi d)' : pure virtual function was not defined
                  C:\pure_virtual .cpp(6) : see declaration of 'Base::func2'


                  <OT>

                  U:\>cl
                  Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
                  Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

                  </OT>

                  --
                  Karthik. http://akktech.blogspot.com .
                  ' Remove _nospamplz from my email to mail me. '

                  Comment

                  • Markus Elfring

                    #10
                    Re: abstract classes not detected by compiler

                    > a constructor cannot call any virtual functions. so any call to a[color=blue]
                    > virtual function will be non-virtual. In consequence calling a
                    > pure virtual function should be rejected by the compiler (IIRC)...[/color]

                    Which rules from the specifications show this restriction?
                    Would you like to adjust your wording?

                    How does your statement fit to the descriptions in the chapter "Item
                    25: Virtualizing constructors and non-member functions" from the book
                    "More Effective C++"?

                    Regards,
                    Markus

                    Comment

                    • Markus Elfring

                      #11
                      Re: abstract classes not detected by compiler

                      > a constructor cannot call any virtual functions. so any call to a[color=blue]
                      > virtual function will be non-virtual. In consequence calling a
                      > pure virtual function should be rejected by the compiler (IIRC)...[/color]

                      How do you think about this?
                      - What is a "virtual constructor"?


                      - Discussion "virtual copy constructor"

                      Comment

                      Working...