0

I try to dive deeper and understand the differences between Public | Private | Protected in a low level perspective, in C++.

How are the differences between the three expressed in the memory?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Or ben aba
  • 35
  • 1
  • 2
  • 7
    There will be no difference to epress these in memory. These are the access modifier and very much language(compiler) specific. – Sanjeev Dec 08 '20 at 13:30
  • this you'll find interresting : https://www.youtube.com/watch?v=SShSV_iV1Ko – engf-010 Dec 08 '20 at 13:31
  • @Snajeev however access specifiers do affect how a types members are layed out in memory. I don't think this is what OP is asking for, but indeed there is a low level aspect of access specifiers – 463035818_is_not_an_ai Dec 08 '20 at 13:35

3 Answers3

5

private, public and protected does not cause members to be stored in specific regions of memory. The access is checked by the compiler. On the very lowest level, there is no difference.

However, access specifiers do have an effect on what guarantees you get on the order in which class members are layed out in memory.

From the C++17 standard draft:

Nonstatic data members of a (non-union) class with the same access control (Clause [class.access]) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (Clause [class.access]). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions ([class.virtual]) and virtual base classes ([class.mi]).

This means, that for

 struct foo {
     private:
        int x;
     protected:
        int a;
        int b;
     public:
        int m;
        int n;
     private:
        int y;
};

You only get the guarantee that in memory x comes before y, a comes before b and m comes before n. Other than that, the order in which the members are layed out in memory is unspecified.

However, rarely the order of members in memory is a useful information. Hence it isn't too wrong to say that access specifiers have nothing to do with "low level memory".

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    The ordering info is interesting. However it does not state anything on whether/how the memory layout affects the accessability. Maybe it is just me reading into the question that OP seems to expect memory access protection to be involved in visibility. – Yunnosch Dec 08 '20 at 13:54
  • @Yunnosch good point, tried to clarify that – 463035818_is_not_an_ai Dec 08 '20 at 13:56
  • Pity. You already had my upvote. Can't give another one. ;-) – Yunnosch Dec 08 '20 at 14:03
  • I think it would also be worth knowing whether or not the compiler can decide to remove private members when it can prove that they are never used. – bitmask Dec 08 '20 at 14:03
  • @bitmask Interesting yes. I think I would feel unpleasantly surprised if it causes unexpected total size... I'd upvote a question asking about this.... – Yunnosch Dec 08 '20 at 14:05
  • @Yunnosch I was under the impression that this is covered by *this* question. However, I am 99% certain that this is *not* allowed. – bitmask Dec 08 '20 at 14:08
  • @bitmask difficult to observe such optimization, other than `sizeof(foo)` being smaller than the sum of its members, which would be rather odd, but I don't know what the standard says about it – 463035818_is_not_an_ai Dec 08 '20 at 14:21
  • 2
    Okay, okay, there you go: https://stackoverflow.com/q/65201486/430766 – bitmask Dec 08 '20 at 15:09
2

At the lowest level (byte representation of objects) there are absolutely no difference between public, private and protected. At most compilers can (but are not required to) reorder members according to their visibility.

At intermediary level (run time behaviour) there is little if any difference. If you can find a public pointer to a private data you can safely use it. Specifically this is different from constness where using a non const pointer to alter const data is explicitely Undefined Behaviour and can cause SIGSEGV errors.

The difference is only at the highest level. You can use public members from anywhere, while private members can only be used in the class where they are declared and protected member can be used from their class and all classes inheriting it - but friendness can allow specific classes of function to access private or protected data.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

Not at all.

The access is "granted/denied" by the compiler.

Any access not matching an appropriate visibility (as controlled by the class of the accessed object, via pointer or not) is prevented before building.

Note:

The other answers usefully discuss the effect of visibility on order in memory.

I howevr answered the different question I read into OPs post "How are memory protection features used to implement member accessability/visibility?", which concerning cause and effect is kind of the reverse question. Or only the ordering/structuring of the members in differently configured memories is the tool to achieve the desired visibility effect, which in turn would require (but not cause) members to be ordered in a certain way.

I.e. I do not see a conflict between answers, just a different interpretation of the question.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • afaik access specifiers do (or did?) affect how a types members are layed out in memory. With a grain of salt OPs question can be interpreted to ask for that – 463035818_is_not_an_ai Dec 08 '20 at 13:37
  • Write an enlightening answer on that and I will happily upvote it and probably delete my answer. Your comment is to brief for me to get the point.... @largest_prime_is_463035818 If the attribute members of the class (which is what I mostly think of with memory layouts) are anything like structs I doubt that they end up in differently behaving memories. Concerning the methods I think the invovled tables are also unlikely to have special memory-crossing layouts. – Yunnosch Dec 08 '20 at 13:39
  • 2
    I'll have to do some reasearch myself. Until then your answer is the best I could come up with too ;) – 463035818_is_not_an_ai Dec 08 '20 at 13:39
  • What a relief. I understood your comment to question my answer. Still, if you write a more detailed one be sure of an upvote. Maybe mine gets a few for a "usefully simplified thinking model" kind of value. Let's see. @largest_prime_is_463035818 – Yunnosch Dec 08 '20 at 13:43
  • I found the relevant quote from the C++17 standard. I know that something changed recently, but I think that was before C++17. – 463035818_is_not_an_ai Dec 08 '20 at 13:49
  • 2
    no, not at all I am saying that your answer is wrong. The issue I outlined in the answer is for me nothing more than a curiosity. For all practical purposes your answer is a little simplified but good enough ;) – 463035818_is_not_an_ai Dec 08 '20 at 13:55
  • @largest_prime_is_463035818 Thanks. I added an explanation of what I see as a different way of reading the question. Seems without conflict to me too. – Yunnosch Dec 08 '20 at 14:02