Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing private struct of a class using auto

Tags:

c++

c++11

I discovered that next weird code compiles and runs (on VS 2019):

#include <iostream>

class Test
{
    private:
    struct Priv
    {
        int a;
    };
    
    public:
    static Priv WeirdFunc() {return {42};}; 
};

int main()
{
    auto val = Test::WeirdFunc();
    std::cout << val.a;
}

Output is 42, no problems here.

The issue I see is that auto keyword allows us to access private structure "Priv". If I try to replace auto with Test::Priv I get compile error, as expected. From the articles on the internet I found out that you can have to use auto for lambdas, but this case was never mentioned.

Also, if I try to output "Test::WeirdFunc().a" it also works

So my questions are:

  • Is it expected behaviour for auto to let us access private structures/classes?
  • Is it allowed to declare public function that returns private structure?
  • Is it expected behaviour that we can access private structures/classes if it's return value of function (e.g. "Test::WeirdFunc().a")?

All of that is obviously terrible code style, but I'm curious about whether it's valid c++ code or not

like image 579
Devaniti Avatar asked Dec 30 '22 19:12

Devaniti


2 Answers

The result of Test::WeirdFunc() is a Priv. This is also the auto-deducted type of val. The auto keyword removes the necessity to name the type of val to be Priv and therefore, the compiler does not complain. As a result, val is of (unmentioned) type Priv and has a public member a, that can be accessed freely.

So the answers to all your questions is: Yes, (as long as you don't "mention" the name of the nested class).

See also: cpp reference on nested classes

like image 145
Emmef Avatar answered Jan 21 '23 05:01

Emmef


So my questions are:

  • Is it expected behaviour for auto to let us access private structures/classes?

Yes.

  • Is it allowed to declare public function that returns private structure?

Yes.

  • Is it expected behaviour that we can access private structures/classes if it's return value of function (e.g. Test::WeirdFunc().a)?

Yes.

All of that is obviously terrible code style, ...

No, not necessarily. Think about e.g. a container class, which defines iterator classes as internal nested types:

class Container {
     class iterator {
     public:
          iterator operator++(); 
          iterator operator++(int); 
     };

public:
     iterator begin();
     iterator end();
};

This allows to access the iterator's instances and operations via auto, but not to directly create instances from outside the class.

like image 37
πάντα ῥεῖ Avatar answered Jan 21 '23 06:01

πάντα ῥεῖ