|
 |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>>> How is it encapsulation if everything is public?
>
>> """
>> A language construct that facilitates the bundling of data with the methods
>> operating on that data.
>> """
>
>> Again, it's the definition you pointed to.
>
> Only if you ignore the data hiding part, which is essential for
> abstraction.
Really, Python isn't noticeably less private than C++. C++ shows you
everything. The compiler says "don't reference that by name", instead of the
IDE doing it.
>> It has so little encapsulation (in the "restricting access" part of the
>> definition) that it might as well not have encapsulation.
>
> You are exaggerating. On purpose.
I disagree. I'm simply expressing an opinion that differs from yours. If I
know something is private, I don't try to access it.
>> In other words, I find that marking something as "private" doesn't give
>> significantly more protection to private data than marking something with an
>> underline does in Python, in practice. In practice, both are trivial to get
>> around, accidentally or on purpose.
>
> You are exaggerating. On purpose.
Again, I disagree. I disagree that C++ refusing to compile when you access
by name something marked as private is significantly more encapsulated than
Python's naming convention that you shouldn't access fields marked with an
underscore by name.
> There's a huge difference. You make it sound like there was no difference
> at all. Just for the sake of argument.
In practice, I disagree. I recognize the difference. I'm just of the opinion
that the difference is so small as to be irrelevant. You think that having
the compiler complain is important. I don't.
Do you think Java doesn't have private members because there's a way of
accessing them via reflection?
> I don't think the C standard guarantees how much padding there will be
> between members of a struct either. The bit representation of a struct
> instance may change from system to system, and even from compiler to
> compiler, and hence you must not make assumptions if you want your program
> to be portable.
Right. But that's far from "makes no guarantees" you see. You often make a
broad sweeping statement, and when I call you on it, you backpedal and then
say I'm exaggerating "on purpose".
>>>> The elements of a structure are all between
>>>> &x and &x + sizeof(x).
>>> No, they aren't. The standard doesn't specify how much padding there may
>>> be between struct elements. The compiler can add as much padding as it wants
>>> (or none at all).
>
>> That doesn't invalidate the formula. I didn't say there was nothing else there.
>
> So you said that "a given type, all by itself, will require sizeof(type)
> bytes of memory". Well, duh, that's how sizeof() is defined, after all.
You said "there are no guarantees". I said yes, there is at least the
guarantee that the elements of a class even with private members are laid
out in the space between the start and the end.
What you mean to say is "there aren't enough guarantees on layout to ensure
that you can do something reasonable in a portable way by breaking
encapsulation." That's far different from "there are no guarantees."
You exaggerate, on purpose. ;-)
> (That doesn't mean you can't have a pointer pointing to a member of an
> object, in a portable way. However, that requires either for the member
> to be public or for the object to give you the pointer.)
Yep. Fully agreed.
>> I didn't say that it did.
> But we are talking about accessing private members here.
I can still do that. I can't do something *useful* with them, but *in
practice*, I can zero out your object by mistake. You may discount that as
irrelevant, but I don't. I don't think that any amount of definition
wrangling is going to resolve *that* disagreement.
Unsafe languages don't keep code from accessing your private variables. They
keep you from reliably portably accessing private variables in a correctly
written system where every piece is bug free. You're taking the latter to
mean the former. I'm not.
>> And besides, I'm just disputing your assertion
>> that the language makes no guarantees about the layout of data.
>
> Well, it doesn't. Not any that would help you accessing them from the
> outside if they are unexposed.
See what you did there?
> (Btw, I didn't mean "doesn't give any guarantees whatsoever". I meant
> "doesn't give any guarantees that would help you resolving the address of
> a private member from the outside in a portable way".)
OK. I'll agree with that. :-)
> But if you had, for example, an array of two unsigneds, I'm not sure the
> standard guarantees they will be at consecutive memory locations, with no
> padding between them. (I could be wrong on this one, though.)
I'm not sure.
> Not that any compiler in the universe would put padding between them,
> mind you, but it's probable that the standard doesn't *force* compilers
> to not to use padding (eg. because an exotic hardware requires it).
Certainly there are machines where floats, for example, need to be on
particular boundaries and which might not be packed to those boundaries.
Stupid design, but conceivable. :-) Of course, on such machines, you
usually can't get a C compiler.
> Well, if "access" means "reading their bit pattern in memory", then yes,
> you can "access" them portably.
And, as I said, you can overwrite them, which *I* feel violates
data-security encapsulation.
> To me, accessing means that you actually read (or even write) a private
> member variable and write code which depends on it.
OK. And to me, "accessing" means reading it or writing it without going thru
the interface defined by the class.
>> memcpy(myarray[0], myarray[1], sizeof(myarray[0])) isn't well-defined?
>
> Only in a very limited set of cases, actually. If myarray consists of
> class instances, the result is undefined behavior (because you are
> bypassing copy constructors).
Fair dinkum.
> With basic types it's well-defined, and maybe for PODs with trivial
> constructors and destructors.
And for structs or classes with no vtable, as those are defined to have the
same layout as in C, and it works in C, yes?
> Well, C++ doesn't stop you from reading the bytes of an object in memory.
> Nobody is denying that.
>
> Whether that constitutes "accessing a private member" is arguable.
Right. I think it is, because if you can change the values of my private
variables without going thru my member functions, I have no way of enforcing
my code's correctness or my invariants.
>>> You mean C++ is causing problems there?
>
>> Oh, you wouldn't believe. Not C++ per se, but unsafe languages in general,
>> poorly organized and badly documented.
>
> Safe languages never cause problems, then?
Safe languages merely make it easier to prove who has the bug. It also tends
to catch the bug when (say) you open the file, instead of 10 minutes later
when you try to parse what you read from it.
>> Yep. Well, honestly, the whole development chain is screwed. Not only is the
>> code buggy, but the authors are unwilling to fix it, describe it, document
>> it, or really take any responsibility at all for its sorry shape.
>
> I'm not sure using a "safe" language would fix those problems either.
Not completely, no. But at least you could assign blame. Right now, if I
write code that invokes their libbrary and it segfaults, yet it doesn't
segfault in their trivial test application that only ever invokes one
operation in the library before exiting, then it must be my fault.
In a safe language, you could say "Look, it throws an exception in your code
. Find where that exception is, and see what causes it."
--
Darren New, San Diego CA, USA (PST)
The question in today's corporate environment is not
so much "what color is your parachute?" as it is
"what color is your nose?"
Post a reply to this message
|
 |