From: Jiang on 15 Sep 2006 14:06 Richard Corden wrote: > Jiang wrote: > > Carlos Moreno wrote: > >> 1) private is only used as class-member access specifier > >> > > > > According to the holly standard, the memory layout > > for variables separated by different access specifiers > > is implementation issue. Therefore if you change > > private to public, the member layout maybe different. > > My understanding is that the standard only talks about 'access > specifiers' not 'different access specifiers'. So I believe that the > layout of the following is unspecified: > > struct A > { > public: > int i; > public: > int j; > }; > True. > However, the point that they maybe different still holds, since it is > unspecified, there is no guarantee that the above will have the same > layout as: > > struct A > { > public: > int i; > private: > int j; > }; > > True. "Separated by different access specifiers" is just a specialized version of "separated by access specifiers". Since this issue is totally unspecified by standard, we can not make sure that replacing private with public will give us the *exactly same* result/layout. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Jiang on 15 Sep 2006 14:05 Carlos Moreno wrote: > Jiang wrote: > > > For following example, > > > > struct B > > { > > int t; > > }; > > > > struct D1 : private B // private inheritance (hold-a) > > { > > D1(){ t = 0; } > > }; > > > > struct D2 : public D1 > > { > > D2(){ t = 0; } // error, B::t is not accessible. > > }; > > > > So, again private and public make difference here. > > If I understand correctly, this example is not valid with respect > to my question -- sure, private and public make a difference, but > is not that what counts; I'm starting with a code *that compiles*; > so, if I haev a privately inherited base class, then my code would > only do what it is allowed to do. *Then* I replace the privately > inherited to a publicly inherited. There shouldn't be any error > now: I'm eliminating restrictions, so whatever I was able to do > before, I'm able to do now, and more (except that, again, my > question describes a situation where I will not do anything more, > since I will *only* change the private keyword to public) > Well, my point is the private inheritance constructs a "hold-a" relationship while public inheritance yields a "is-a" relationship. If you replace private with public, you create a inheritance chain, which is not available in the original configuration. Please check the nice examples purposed by Kanze and Falk. > > Actually I do not known any compilers really treat > > private and public member differently, because > > access specifiers are purely logical constructs. > > My thinking exactly. Private does not determine behaviour; it > simply places semantic restrictions on what the program is > allowed to do, not on the behaviour resulting from what the > program does do. > Not true for case 2. My above comment was based on case 1. And even for case 1, it is pretty valid that the compilers can allocate private members in higher address, and put all public members in other region, because here the allocation order is unspecified behavior according to the standard. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Greg Herlihy on 15 Sep 2006 14:18 Pete Becker wrote: > Carlos Moreno wrote: > > > > If I now replace every single instance of the keyword private > > with the keyword public (and I change *nothing else*), would > > the behaviour of my program change? That is, in practical > > terms, should I expect the behaviour of my program to change > > when compiled with an *actual* compiler that is reasonably > > compliant and reasonably high-quality? > > > > Unlike Java, in C++ private members are considered in name lookup, so > changing private to public doesn't affect lookup. It does, of course, > affect accessiblity, but that means that some things that used to be ill > formed because name lookup found something that wasn't accessible would > become well formed. Since the program was well formed to begin with, > that doesn't apply. The behavior of the program will be the same. (And > any compiler that gets this wrong is so fundamentally broken that it's > not on the market) There is always the possibility that changing "private" to "public" with a macro could turn a well-formed program into an ill-formed one: class A { class B; private: class B {}; }; will compile with private as "private", but will not compile with private as "public". Greg [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Carlos Moreno on 15 Sep 2006 14:19 kanze wrote: > "A translation unit that includes a header shall not contain any > macros that define names declared or defined in that header. > Nor shall such a translation unit define macros for names > lexically identical to keywords." (I think that the first > sentence is rather weak. It suggests that "#define allocator > 42" would be legal before including <vector>, since allocator > isn't defined in <vector>, but in <memory>. But obviously, > <vector> is going to include <memory>.) Nit pick: I believe your reasoning is incorrect -- well, at least one can object. It comes down to what we call "defined in that header" -- If <vector> includs <memory>, then allocator is defined in the header <vector> -- The header <vector> has several ways of #defining a symbol; one of them is to use a #define directive; another one is to #include a header where the symbol is defined (notice the recursive nature of my "definition". Anyway, perhaps a better phrasing would have been: "names that the header declares or defines" -- this is, IMO, unambiguous, since it doesn't say anything that suggest a given mechanism to declare or define. Anyway, coming back to the original point: since my question is rather practical in nature, and not "language lawyering", I'm now curious as to whether I should expect any concrete manifestation (read: nasty effect) of that undefined behaviour that occurs when I #define private having included standard headers... >>An object containing different access types may be laid out in >>an implementation-defined manner. Changing the access >>specifiers may cause the implementation to change the ordering >>of the members. [...] > > This could also cause a change in behavior. [...] > A anA ; > if ( &anA.a > &anA.b ) //... > > In this case, of course, the code has unspecified behavior to > begin with [...] > I don't think that this was what Carlos had in mind Indeed. I mentioned that I start off with a strictly legal C++ program -- I'm not sure if that implies, strictly speaking, unspecified or implementation-dependent behaviour, but in my mind, I was assuming that the program that I start with is clean enough that it doesn't have any sort of nasties like the above. Still, you make a very good and very interesting point, if only for the fun of thinking about it, and not for the practical implication it may have with respect to my original question. >>My vote is: behavior no; binary image maybe. > > The actual examples outvote you, two to one:-). :-) It still looks like for the use that I have in mind, which implies the assumption that I'm starting with a program that is clean enough and that it does not have bahaviour that is unspecified, implementation dependent, or undefined, my initial guess seems correct (assuming that the undefined effect resulting from #defining a keyword having #included standard headers does not materialize in practice, with actual compilers and actual standard library implementations). Thanks, Carlos -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Carlos Moreno on 15 Sep 2006 14:20 Jiang wrote: > Actually I do not known any compilers really treat > private and public member differently, because > access specifiers are purely logical constructs. > > But I do not have a good reason to do such a > replacement. :-) No one has explicitly asked me to say why I was asking such a strange question. But having seen a few interesting replies, it could be a good thing to mention that detail. What I have in mind is debugging/testing (QA kind of testing). Having client code (the "test protocol") access to private data members gives you more flexibilty in terms of easily creating test case scenarios. Of course, if we're talking production code, I wouldn't want to even open the source file with a text editor after the test protocols passed! In particular, changing all the private to public is about the worst possible idea!! First of all, one could *accidentally* change something else that goes unnoticed. One could then, after all the test protocols passed and we want to restore the original file, *forget/overlook* to change back one or several of the publics, leading to future bugs or trouble. Also, though less severe consequences, we could accidentally change a public back to private when that one was originally a public, leading to unnecessary annoyment. That's why I thought #defining private as public for the purpose of compiling the prorgam that runs the test protocols would be the least intrusive and safest way to do that trick. #Defining it from the command-line with a compiler switch is the safest way. One concern, however, is due to the fact that the generated binaries could change -- that forces us to remember to recompile the non-testing version right after we're finished; otherwise, if we leave the object file and there are no more changes to the corresponding source file, the next time that we link it (because other modules changed), we might run into trouble, since some of the object files are compiled with one class declaration, and the object file that we tested in the past with a different declaration, leading to inconsistent binaries (that is, there is the possibility). Carlos -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Callback-related libraries and terminology Next: fgets() vs std::getline() performance |