Why doesn't the compiler complain about catch clauses?

This code generates C2248 : 'A::B::ExceptionB' : cannot access private class declared in 'class A::B' in VS2008.

 #include <iostream> class A { class ExceptionA{}; class B { class ExceptionB{}; public: B(); }; public: A(int); }; A::B::B() { throw ExceptionB(); } A::A(int i) { i % 2 ? throw ExceptionA() : throw A::B::ExceptionB(); // C2248 !! } int main() { try { A a(3); } catch( A::ExceptionA& ) { std::cout << "A::ExceptionA" << std::endl; } catch( A::B::ExceptionB& ) { std::cout << "A::B::ExceptionB" << std::endl; } } 

Of course, if I create an ExceptionB{} public class in B , the code compiles.

But I don’t understand why the compiler does not complain about 2 catch clauses in main() , since A::ExceptionA is a private class in A and A::B::ExceptionB is a private class in A::B

+4
source share
2 answers

The question is formulated somewhat strange, so I assume that you are asking why

 i % 2 ? throw ExceptionA() : throw A::B::ExceptionB(); 

not compiled, but

 catch( A::ExceptionA& ) catch( A::B::ExceptionB& ) 

does.

If you look at a copy of your handy standard C ++ standard (chapter 11, paragraph 4), it says the following:

It should be noted that this is access to elements and base classes that are controlled, and not to their visibility. Member names are still visible, and implicit conversions to base classes are still considered when these members and base classes are not available.

The difference is that in the first case, you are trying to call a member A::ExceptionA or A::B::ExceptionB - the constructors for the exception. But in the output of catch, you do not get access to a member of any of them; you only get access to the type name.


However, I still think this is a bug in MSVC ++. The standard also reads in chapter 15.6, paragraph 1:

If the exception declaration in the catch clause has a class type, and the function in which the catch clause does not have access to the destructor of this class, the program is poorly formed.

which your sample seems to violate, but MSVC ++ accepts it without complaint.

+3
source

Both exceptions are private, and g ++, clang and EDG all complain about this. That is, it's probably a bug in C ++ to use them the same way you do, but your compiler seems to be wrong about the code. However, the section on exception handling does not explicitly state that an exception that needs to be caught needs some access (in the end, a private class will be available in member "A"). I suppose this caused developers to not check this access.

+1
source

Source: https://habr.com/ru/post/1400833/


All Articles