3

Consider the below code snippet.

The method Sayhi() is having public access in class Base.

Sayhi() has been overridden as a private method by the class Derived.

In this way, we can intrude into someone's privacy and C++ has no way to detect it because things happen during run-time.

I understand it is "purely" compile-time check. But when using some thick inheritance hierarchy, programmers may incorrectly change access specifiers. Shouldn't the standard have some say atleast? some kind of warning message.

Why doesn't the compiler issue atleast a warning message whenever access specifier of overridden or virtual functions differ?

Q1. Does C++ standard has any say about such run-time anomalies?

Q2. I want to understand from C++ standard's perspective, why wouldn't standard enforce compiler implementors to have warning diagnostics?

#include <iostream>

class Base {
    public:
        virtual void Sayhi() { std::cout<<"hi from Base"<<std::endl; }
};

class Derived : public Base
{
    private:
        virtual void Sayhi() { std::cout<<"hi from Derived"<<std::endl; }
};


int main() {
    Base *pb = new Derived;
    // private method Derived::Sayhi() invoked.
    // May affect the object state!
    pb->Sayhi(); 
    return 0;
}
Arun
  • 2,087
  • 2
  • 20
  • 33

3 Answers3

7

Does C++ standard has any say about such run-time anomalies?

No. Access control is purely compile-time, and affects which names may be used, not which functions may be called.

So in your example, you can access the name Base::Sayhi, but not Derived::Sayhi; and access to Base::Sayhi allows you to virtually call any function that overrides it.

Why wouldn't standard enforce compiler implementors to have warning diagnostics?

The standard has nothing to say about warnings at all; it just defines the behaviour of well-formed code. It's up to compiler writers to decide what warnings might be useful; and warning about all private overrides just in case you didn't mean them to be overrides sounds like it would generate a lot of false positives.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • yes, I understand it is "purely" compile-time check. But when using some thick inheritance hierarchy, programmers may incorrectly change access specifiers. Shouldn't the standard have some say atleast? some kind of warning message. – Arun Apr 19 '13 at 15:24
  • @Arun: The problem is with *"programmers may incorrectly change access specifiers."*. With C and C++ you are allowed to shoot yourself in head, doesn't mean one should. There is no excuse for writing bad code. It is simply wrong to expect compiler to detect bad code. It is responsibility of the programmer not the compiler. – Alok Save Apr 19 '13 at 15:26
  • @Alok, yes I understand all that you want to convey, but had some bad time fixing someone's code! Things could have eased out with just a warning message, something which programmers wouldn't ignore when having a bad time you see :) – Arun Apr 19 '13 at 15:32
  • @Arun: The standard has nothing to say about warnings at all; it just defines the behaviour of well-formed code. It's up to compiler writers to decide what warnings might be useful; and warning about all private overrides just in case you didn't mean them to be overrides sounds like it would generate a lot of false positives. – Mike Seymour Apr 19 '13 at 15:33
  • @Mike, it makes sense, thanks for clarifying from the perspective of C++ standard. – Arun Apr 19 '13 at 15:41
  • @Arun Its not necessarily a warning. It is sometimes necessary that particular function is called via base class reference/pointer. Access specifiers/constness refer only that particular symbol. For eg, you can call a private member function via a member function pointer. Its up to the programmer to take care of such errors – balki Apr 19 '13 at 17:55
2

Access specification cannot be loosened it can only be tightened up.
Sayhi() is public in Base class so basically all classes deriving and overidding from it should expect the method to be public, there is no intrusion. The access specification for overidding functions is well specified since the method was declared public to begin with.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • The intrusion is from the POV of the `Derived` class, which thinks that it is defining a `private` function. Then along comes the `Base`, and all of a sudden (maybe not until v1.1) `SayHi` is an override. So, (1) this an instance of fragile base class, all it really means is that derived classes must pay attention to their bases; and (2) adding a virtual function to a base class *is a source-backward-incompatible change* if you consider privacy as something that should be preserved. And a binary-incompatible change too, ofc, but that is obvious whereas the source incompatibility might not be. – Steve Jessop Apr 19 '13 at 16:19
0

Even though your question has been answered by now, I would like to add a note.

While you consider this as an "anomaly" and would like to have diagnostics, this is actually useful: You can ensure that your implementation can only be used polymorpically. The derived class should only have a public ctor and no other public functions, all the re-implemented member functions should be private.

Ali
  • 56,466
  • 29
  • 168
  • 265