 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Carlos Moreno Guest
|
Posted: Fri Sep 15, 2006 4:57 am Post subject: Sanity check: public/private |
|
|
Say that I have a C++ program that consists only of perfectly
valid C++ code (in other words, the program compiles and does
not invoke undefined behaviour).
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?
As a corollary: if I simply add, at the beginning of the
file, the following line:
#define private public
And change *nothing else*, would I expect the behaviour of
the program to change?
As a corollary of the corollary, how about using the compiler
switch -Dprivate="public" to introduce the #defined symbol
without touching the source code? (I guess this is exactly
the same as the previous case, right?)
In all of the above: should I expect the generated machine
code to change? (assuming all the compiler switches and
optimization settings are exactly the same)
The answer that my mind gives me is: not sure about the
machine code; but for the behaviour of the prorgam: no,
it does not change -- I can't think of any reason why it
could change; but never say never, and I'm sure with the
armada of experts and gurus out there, if there is any
such reason, I will find out :-)
If necessary, please divide the answer into the following
two cases:
1) private is only used as class-member access specifier
2) private is also used for inheritance.
(I believe the answer NO is valid for both cases, but I'm
mostly interested in case (1), so if the answer is different,
please specify the reasoning for both cases).
Thanks for any comments,
Carlos
--
PS: Reasons why I'm asking this could be provided upon
request -- it's just that this post is already long
enough.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Jack Klein Guest
|
Posted: Fri Sep 15, 2006 9:00 am Post subject: Re: Sanity check: public/private |
|
|
On 14 Sep 2006 19:57:17 -0400, Carlos Moreno
<moreno_at_mochima_dot_com (AT) mailinator (DOT) com> wrote in
comp.lang.c++.moderated:
| Quote: |
Say that I have a C++ program that consists only of perfectly
valid C++ code (in other words, the program compiles and does
not invoke undefined behaviour).
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?
|
I would not expect the behavior to change.
| Quote: | As a corollary: if I simply add, at the beginning of the
file, the following line:
#define private public
|
I am pretty sure that using a macro to redefine a keyword is undefined
in C++, but I will admit that I couldn't find that in a quick look at
the standard. But let's assume it does not, or your implementation
ignores it.
| Quote: | And change *nothing else*, would I expect the behaviour of
the program to change?
|
The behavior of the program should not change for any reason that I
can think of.
| Quote: | As a corollary of the corollary, how about using the compiler
switch -Dprivate="public" to introduce the #defined symbol
without touching the source code? (I guess this is exactly
the same as the previous case, right?)
|
Ignoring (possible) undefined behavior, and assuming that the compiler
option does what most compilers do with it, since the language does
not define this method of defining a macro, I still agree I would not
expect a change in behavior.
| Quote: | In all of the above: should I expect the generated machine
code to change? (assuming all the compiler switches and
optimization settings are exactly the same)
|
Here there's a much better chance of seeing a change, especially if
the class initially had public and private members before you changed
them all to public.
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
would likely cause the machine code to change, as some instructions
might well include the offset in an address or as an index to a
pointer.
| Quote: | The answer that my mind gives me is: not sure about the
machine code; but for the behaviour of the prorgam: no,
it does not change -- I can't think of any reason why it
could change; but never say never, and I'm sure with the
armada of experts and gurus out there, if there is any
such reason, I will find out :-)
If necessary, please divide the answer into the following
two cases:
1) private is only used as class-member access specifier
2) private is also used for inheritance.
(I believe the answer NO is valid for both cases, but I'm
mostly interested in case (1), so if the answer is different,
please specify the reasoning for both cases).
Thanks for any comments,
Carlos
|
My vote is: behavior no; binary image maybe.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Jiang Guest
|
Posted: Fri Sep 15, 2006 9:02 am Post subject: Re: Sanity check: public/private |
|
|
Carlos Moreno wrote:
| Quote: |
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.
| Quote: | 2) private is also used for inheritance.
|
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.
Someone could use above behavior to implement
compile-time checking/assertion, maybe.
| Quote: | (I believe the answer NO is valid for both cases, but I'm
mostly interested in case (1), so if the answer is different,
please specify the reasoning for both cases).
|
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. :-)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Richard Corden Guest
|
Posted: Fri Sep 15, 2006 7:00 pm Post subject: Re: Sanity check: public/private |
|
|
Jiang wrote:
| Quote: | 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;
};
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;
};
Regards,
Richard
--
Richard Corden
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Sep 15, 2006 7:03 pm Post subject: Re: Sanity check: public/private |
|
|
Jack Klein wrote:
| Quote: | On 14 Sep 2006 19:57:17 -0400, Carlos Moreno
moreno_at_mochima_dot_com (AT) mailinator (DOT) com> wrote in
comp.lang.c++.moderated:
Say that I have a C++ program that consists only of
perfectly valid C++ code (in other words, the program
compiles and does not invoke undefined behaviour).
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?
I would not expect the behavior to change.
|
class B
{
} ;
class D : private B
{
} ;
int
main()
{
try {
throw D() ;
} catch ( B const& ) {
return 0 ;
} catch ( D const& ) {
return 1 ;
}
return 2 ;
}
Or:
struct B
{
virtual ~B() {}
} ;
struct D : private B
{
B* myB() { return this ; }
} ;
int
main()
{
B* p1 = (new D)->myB() ;
D* p2 = dynamic_cast< D* >( p1 ) ;
return p2 == 0 ;
}
Compiling with -Dprivate=public results in a different return
value in each case. (It also results in a warning that the
second catch clause cannot be activated in the first example.)
| Quote: | As a corollary: if I simply add, at the beginning of the
file, the following line:
#define private public
I am pretty sure that using a macro to redefine a keyword is
undefined in C++, but I will admit that I couldn't find that
in a quick look at the standard.
|
It's not, as long as you don't include a standard header.
(That's why my two examples above depend on a difference in the
return code, rather than outputting something.) §17.4.3.1.1/2:
"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>.)
Why should defining a macro to change a keyword be a problem
otherwise?
| Quote: | But let's assume it does not, or your implementation
ignores it.
And change *nothing else*, would I expect the behaviour of
the program to change?
The behavior of the program should not change for any reason
that I can think of.
|
See above. It does. (At least with g++, but I'm pretty sure
that it is conformant here.)
[...]
| Quote: | 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 would likely cause the machine code to
change, as some instructions might well include the offset in
an address or as an index to a pointer.
|
This could also cause a change in behavior. Imagine a compiler
which always places private members first, and otherwise
respected the order of declaration. Then, given:
struct A
{
int a;
private:
int b;
}
A anA ;
if ( &anA.a > &anA.b ) //...
In this case, of course, the code has unspecified behavior to
begin with, and so the change falls within a much larger set of
possible changes. In theory, at least, a compiler could change
the order of evaluation in an expression according to whether
elements were private or public; if the observable behavior of
the program depended on such ordering, it would change.
I don't think that this was what Carlos had in mind, but it is
certainly clear that in any program which has several possible
legal behaviors, changing private to public could potentially
change the behavior.
In practice, I don't know of a compiler where this would be the
case (but the behavior may change for other reasons, e.g.
different optimization options).
| Quote: | The answer that my mind gives me is: not sure about the
machine code; but for the behaviour of the prorgam: no, it
does not change -- I can't think of any reason why it could
change; but never say never, and I'm sure with the armada
of experts and gurus out there, if there is any such reason,
I will find out :-)
If necessary, please divide the answer into the following
two cases:
1) private is only used as class-member access specifier
|
I think that it was once an expressed goal that changing private
to public here would make no difference in the specified
observable behavior of a program. As pointed out above, it's
rather obvious that it is allowed to make a difference when more
than one behavior is acceptable, i.e. the order of evaluation in
an expression---such differences may occur even without any
change to the code; differences due to data layout are
explicitly possible as well, beyond the ones normally possible,
but these, too, are due to differences allowed in the data
layout only in the case where some of the data is private.
| Quote: | 2) private is also used for inheritance.
|
There are definite, explicit and required differences here, as
shown above.
| Quote: | (I believe the answer NO is valid for both cases, but I'm
mostly interested in case (1), so if the answer is
different, please specify the reasoning for both cases).
My vote is: behavior no; binary image maybe.
|
The actual examples outvote you, two to one:-).
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Fri Sep 15, 2006 7:04 pm Post subject: Re: Sanity check: public/private |
|
|
Carlos Moreno wrote:
| Quote: | 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?
[...]
If necessary, please divide the answer into the following
two cases:
1) private is only used as class-member access specifier
2) private is also used for inheritance.
(I believe the answer NO is valid for both cases, but I'm
mostly interested in case (1), so if the answer is different,
please specify the reasoning for both cases).
|
At least in the second case, program behaviour may change:
______________________ Example 1 ____________________________
#include <ostream>
#include <iostream>
struct base {};
struct derived : private base {};
int main()
{
try
{
throw derived();
}
catch(base&) { std::cout << "Caught 'base'.\n"; }
catch(derived&) { std::cout << "Caught 'derived'.\n"; };
return 0;
}
______________________ Example 2 ____________________________
#include <ostream>
#include <iostream>
struct base { virtual ~base() {} };
struct derived : private base { base* base_ptr() { return this; } };
int main()
{
std::cout << std::boolalpha
<< (dynamic_cast<derived*>(derived().base_ptr()) != 0) <<
'\n';
return 0;
}
_____________________________________________________________
Falk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Martin Bonner Guest
|
Posted: Fri Sep 15, 2006 7:12 pm Post subject: Re: Sanity check: public/private |
|
|
Jack Klein wrote:
| Quote: | On 14 Sep 2006 19:57:17 -0400, Carlos Moreno
moreno_at_mochima_dot_com (AT) mailinator (DOT) com> wrote in
comp.lang.c++.moderated:
Say that I have a C++ program that consists only of perfectly
valid C++ code (in other words, the program compiles and does
not invoke undefined behaviour).
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?
I would not expect the behavior to change.
As a corollary: if I simply add, at the beginning of the
file, the following line:
#define private public
I am pretty sure that using a macro to redefine a keyword is undefined
in C++, but I will admit that I couldn't find that in a quick look at
the standard. But let's assume it does not, or your implementation
ignores it.
And change *nothing else*, would I expect the behaviour of
the program to change?
The behavior of the program should not change for any reason that I
can think of.
As a corollary of the corollary, how about using the compiler
switch -Dprivate="public" to introduce the #defined symbol
without touching the source code? (I guess this is exactly
the same as the previous case, right?)
Ignoring (possible) undefined behavior, and assuming that the compiler
option does what most compilers do with it, since the language does
not define this method of defining a macro, I still agree I would not
expect a change in behavior.
In all of the above: should I expect the generated machine
code to change? (assuming all the compiler switches and
optimization settings are exactly the same)
Here there's a much better chance of seeing a change, especially if
the class initially had public and private members before you changed
them all to public.
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
would likely cause the machine code to change, as some instructions
might well include the offset in an address or as an index to a
pointer.
The answer that my mind gives me is: not sure about the
machine code; but for the behaviour of the prorgam: no,
it does not change -- I can't think of any reason why it
could change; but never say never, and I'm sure with the
armada of experts and gurus out there, if there is any
such reason, I will find out :-)
If necessary, please divide the answer into the following
two cases:
1) private is only used as class-member access specifier
2) private is also used for inheritance.
(I believe the answer NO is valid for both cases, but I'm
mostly interested in case (1), so if the answer is different,
please specify the reasoning for both cases).
Thanks for any comments,
Carlos
My vote is: behavior no; binary image maybe.
|
Actually, I think it might change if the behaviour depends on
implementation defined behaviour. Consider
struct Example {
public: char a;
private: int b;
private: char c;
.....
};
If you have some code which bahaves differently if the address of b is
less or greater than the address of a, then you are into implementation
dependant behaviour (which is OK). The implementation (and hence the
program) MIGHT behave differently if private turns into public.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Fri Sep 15, 2006 7:13 pm Post subject: Re: Sanity check: public/private |
|
|
Carlos Moreno wrote:
| Quote: |
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)
--
-- Pete
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Carlos Moreno Guest
|
Posted: Fri Sep 15, 2006 7:24 pm Post subject: Re: Sanity check: public/private |
|
|
Jiang wrote:
| Quote: | 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)
| Quote: | 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.
Carlos
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Jiang Guest
|
Posted: Fri Sep 15, 2006 11:05 pm Post subject: Re: Sanity check: public/private |
|
|
Carlos Moreno wrote:
| Quote: | 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.
| Quote: | 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! ] |
|
| Back to top |
|
 |
Jiang Guest
|
Posted: Fri Sep 15, 2006 11:06 pm Post subject: Re: Sanity check: public/private |
|
|
Richard Corden wrote:
| Quote: | 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.
| Quote: | 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! ] |
|
| Back to top |
|
 |
Greg Herlihy Guest
|
Posted: Fri Sep 15, 2006 11:18 pm Post subject: Re: Sanity check: public/private |
|
|
Pete Becker wrote:
| Quote: | 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! ] |
|
| Back to top |
|
 |
Carlos Moreno Guest
|
Posted: Fri Sep 15, 2006 11:19 pm Post subject: Re: Sanity check: public/private |
|
|
kanze wrote:
| Quote: | "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...
| Quote: | 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.
| Quote: | 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! ] |
|
| Back to top |
|
 |
Carlos Moreno Guest
|
Posted: Fri Sep 15, 2006 11:20 pm Post subject: Re: Sanity check: public/private |
|
|
Jiang wrote:
| Quote: | 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! ] |
|
| Back to top |
|
 |
Andrei Polushin Guest
|
Posted: Sat Sep 16, 2006 5:15 am Post subject: Re: Sanity check: public/private |
|
|
Carlos Moreno wrote:
| Quote: | 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. :-)
[...]
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.
|
You may encounter problems at least with Visual C++ (other compilers
may behave this way): it uses different name linkage for private
functions. In particular, the following program will not link:
----------------------------------------------- A.h
class A {
private:
void f();
};
----------------------------------------------- A.cpp
#include "A.h"
void A::f() { } // linker symbol "private: void A::f()"
----------------------------------------------- main.cpp
#define private public
#include "A.h"
int main()
{
A a;
a.f(); // linker: unresolved "public: void A::f()"
}
-----------------------------------------------
| Quote: | In particular, changing all the private to public
is about the worst possible idea!!
|
I agree, you are to use public interfaces in your tests.
The recommendation is a more granular design: every unit is rather
small and has testable public interface, even if some units are
private for casual user. E.g. we can use forward declarations to make
some classes privately declared. Or we can use "pimpl" idiom to hide
private dependencies with their declarations.
--
Andrei Polushin
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|