CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Is a non-virtual member function without an implementation legal ?

    I noticed something strange in VC 6. Take the following code :

    PHP Code:
    class CTest {
    public:
        
    CTest()
        {
        }

        
    void CalledFunc();
        
    void NotCalledFunc();
    };

    void CTest::CalledFunc()
    {
    }

    int main()
    {
        
    CTest *ptst = new CTest;

        
    ptst->CalledFunc();
        
    delete ptst;
        return 
    0;

    This compiles and runs correctly, even though I've never provided an implementation of NotCalledFunc. Should it not give me at least an unresolved external error during compilation, or is this behaviour specified like this in the C++ standard ?

    The reason why this happens in VC seems obvious. The compiler automatically strips away functions which are never called, so that the implementation of NotCalledFunc is never actually needed.
    Last edited by Yves M; September 5th, 2002 at 01:13 PM.
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  2. #2
    Join Date
    Jun 2002
    Location
    Letchworth, UK
    Posts
    1,020
    Does the same on Sun, HPUX, Watcom, Borland and Code Warrior compilers but I don't know whether it is legal or not.
    Succinct is verbose for terse

  3. #3
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Interesting... Well, it might be legal then...

    There is of course not much point in doing this, but it would be nice if the compiler could warn me that I haven't implemented functions which I've declared :/

  4. #4
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    Absolutely fine. No problem. Totally legal.

    It's the simplest way of denying copy semantics to a class:
    Code:
    class foo
    {
    public:
        // whatever
    
    private:
        foo(const foo&);   // No definition
        void operator=(const foo&); // No definition
    };
    There's no need to define the copy ctor or the copy assign, since they can't be called from outside the class, and you're not going to call them from inside the class (are you?).

    The linker will warn you if you try to use an undefined (accessible) function.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  5. #5
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Interesting

  6. #6
    Join Date
    Jun 2002
    Location
    Letchworth, UK
    Posts
    1,020
    We use the "denying copy semantics" a lot. And yes, I've just looked - there is no code for it.
    Succinct is verbose for terse

  7. #7
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    As a sort of opposite to that, Yves, were you aware that you are allowed to provide a body for a pure virtual function?
    Code:
    class foo
    {
    public:
        virtual ~foo(){}
        virtual void f() = 0;
    };
    
    void foo::f()
    {
        // Do something
    }
    
    class bar : public foo
    {
    public:
        void f() { foo::f(); }
    };
    So what's the point of that?

    Consider if foo::f() had not been declared pure (all else unchanged). What we are saying when we provide a body for a virtual function in a base class is "here is a default implementation". Consider if a derived class does not provide an override for that virtual function - the derived class will display the default behaviour (from the base class). Now, what if not providing the override was a mistake? How long before that mistake is discovered? No compilation error, no link error, probably no run-time error, just peculiar behaviour.

    In the example I gave above, the designer of foo is saying:

    "Here is a default implementation of function f(). If you wish to use that default, you must make a conscious decision to do so."

    Note that, if you forget to override f in bar, then bar becomes an abstract class (because foo is abstract), so any attempt to create a bar object will throw a compilation error. Much easier to track down.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  8. #8
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    Now that I didn't know. Neat.

    Jeff

  9. #9
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Interesting point, Graham, I didn't know that one either

    I have to say that class structures in C++ are much more expressive than in Java. It is probably a good thing. I guess that's part of why C++ takes so much longer to learn
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  10. #10
    Join Date
    Apr 1999
    Posts
    76

    Thumbs up

    Of course it's legal. I usually declare my functions in a class well before I get around to defining them. I'd hate to have to write stubs before I could compile and run, to checkout a few functions in the begining.

  11. #11
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,867
    Here's something else that's little known. In fact I was programming for years before I realised this....

    What exactly is a virtual function? For years I always thought you had to declare a function as virtual in order to override it in a derived class. In fact I'm certain I've read that in lots of text books. Not so in fact. A function in a base class can be overridden in a derived class regardless of whether it is virtual or not. However, if it isn't declared as virtual and some function in the base class calls it, the base class function will be called by the base class and the derived function will be called by the derived class. What 'virtual' does is to allow a base class to 'know about' (and therefore call) equivalent functions in a derived class. Neat eh?

    We live and learn (well I certainly do!)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured