![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Darren New wrote:
> > 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.
> Or, to phrase it a different way, I've never had a problem caused by someone
> intentionally accessing a private member in a Python-like environment that
> would have been solved by making the code not compile when that happens.
And I have never had a problem with a wild pointer modifying the private
members of a class either.
Is your anecdotal evidence better than mine?
> Have you ever known someone to accidentally name a C function __XYZ__ and
> not be aware they might be stepping on the compiler's namespace?
Actually it's quite common in C and C++ out there to have names starting
with underscore even though the standard says it shouldn't be done.
> Is it
> really a problem that the compiler doesn't prevent you from using names like
> that?
Well, it is quite a common objection in C++ groups when people post code.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> Warp wrote:
> > (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.)
> Actually, just thinking about it a bit more, if the class returns a pointer
> to a member variable, and you can look in the header and see that pointer is
> in an array, then you have a well-defined way of accessing the other private
> data in the same array.
Only if you also know which array element it's pointing to. (If you know,
then the class is, effectively, exposing the entire array.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> 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.
>
> Then show me correct C++ which reads a certain private member variable of
> a class, eg. by reading its value to a variable of the same type, without
> the class deliberately exposing it. (Note that the class may have eg. virtual
> functions.)
Do you understand what I mean by "significant"?
Look, you understand what I'm saying, I'm sure. I understand where you're
coming from. Now you're just trying to tell me my opinion of what's
important is incorrect, simply because you don't find it to be important.
*I* just don't see any practical advantage of having the compiler enforce
that. You gave an example from your function library. I contend that the
same thing could have been done with Python's level of encapsulation. It
would be no more of an error for me (say) to change how variables that start
with "_" work than it would be for you to change the size of the class you
wrote.
*Correct* Python code doesn't rely on "_" members remaining the same from
one release of code to the next. Just because the compiler doesn't enforce
it doesn't mean it's "correct".
>>> 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.
>
> In practice? Well, then show me in practice. Some actual code, please.
For what, writing to private variables, or reading from them? In practice,
bugs clobber data they shouldn't in unsafe languages.
>> 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".
>
> You are calling me a liar now?
No. Merely noting a trend. You don't always say precisely and clearly what
you mean, and when I give counter-examples, you clarify and then act
indignant that I addressed what you said instead of what you meant.
> I might well claim that you "backpedaled" when you first claimed that
> C++ has *no* encapsulation, and later changed it to "little" encapsulation.
I did indeed. It has a small amount of encapsulation, but not enough (IMO)
to be significant. I granted you that one.
>>> 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 was talking about the memory layout of an object. There *are* no
> guarantees about it.
Yes, there are. There's even one I pointed out to which you said "Well, duh,
that's the definition." Remember?
You weren't talking about "guarantees about the memory layout of an object."
You were apparently talking about "guarantees about the memory layout of an
object that would let you safely and portably access private member
variables of an arbitrary class without invoking undefined behavior."
And *I* am saying those qualifiers reduce the utility of the form of
encapsulation that C++ provides.
>> 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.
>
> You seriously don't understand the difference between "size" and "layout"?
I do. Do you seriously tell me that knowing there isn't data from another
object between the lowest-addressed private member and the highest-addresses
private member isn't a guarantee about the layout of the data of a class?
If I take the sizeof a child class, it's always going to be at least as
large as the sizeof a parent class. If I have a class with two members of
class X, it's going to be at least twice as large as class X, even if that
means there are two vtable entries where one would be enough. If I have
class X that inherits multiply from class A and class B, I know that I can
take a pointer to class B and not worry that there are bits of A mixed up
inside.
What you're seeing as "so obvious it doesn't need to be mentioned" is
exactly what I'm saying are the guarantees. :-) These sorts of things
certainly aren't guaranteed in any number of other languages. (For example,
IIRC, member variables in C# that are shared amongst multiple lambda
expressions in the same class wind up being allocated in an area outside
what would be the "sizeof" area of an instance of the class they're declared
in, because they have to outlast the actual instance variable. Again, IIRC.)
> Then, as said in earlier posts, there are no languages with encapsulation
> because you can't physically protect data from being corrupted. There can
> always be a glitch somewhere that corrupts it.
I'll grant you that there are no language implementations on real computers
that guarantee 100% encapsulation. However, that doesn't mean that any
amount of encapsulation is equivalent to any other amount.
What's more isolated? A thread, or a process, or multiple independent
processes all running in the same address space? Well, certainly, if all
your code is 100% correct, you don't need separate processes at all, right?
All you have to do to keep from having to reboot your 8086 is just write
correct code, and no problem.
You may argue that encapsulation hasn't anything to do with correctness. I
disagree. That's OK. We can agree not to agree on that point.
> (By your principle of "if it can't be protected from everything it's not
> worth protecting at all",
That's not my principle. My principle is "if you write your combination on
the outside of the lock, it's not a very secure lock." Sure, it has all the
attributes of a good lock, and it might be impossible to pick, but I'll take
the one that doesn't come with the combination painted on it.
> You don't use a debugger to resolve where the crash happens?
That's the thing, see. When someone comes along and stomps all over the
stack, you can't really prove what's happening very easily, even with a
debugger.
I suppose if we went out and bought a few hundred thousand dollars worth of
hardware debugging hardware, JTAGs and stuff like that, we could find who is
writing outside the stack. Unfortunately, clobbering stuff you shouldn't
clobber doesn't really cause a detectable error until much later sometimes.
More importantly, there's no way to ensure that *your* code isn't clobbering
*their* code, so there's always an excuse not to look at it if it works for
their test code. I.e., if there's a bug in my code that clobbers their
private/static variables before they even get called, the same symptoms
might manifest.
Unfortunately, running a device driver under a debugger works poorly without
hardware support. Plus, we barely fit the system under test in the address
space, let alone the debugger as well.
Apparently the entire industry is this screwed. Which would certainly
explain why in the time the phone system has evolved from cell phones that
take two hands to carry into iPhones, the set top box industry still can't
get digital video or even web pages onto the television.
--
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
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> Darren New wrote:
>>> 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.
>
>> Or, to phrase it a different way, I've never had a problem caused by someone
>> intentionally accessing a private member in a Python-like environment that
>> would have been solved by making the code not compile when that happens.
>
> And I have never had a problem with a wild pointer modifying the private
> members of a class either.
>
> Is your anecdotal evidence better than mine?
No. That's why it's a matter of opinion.
>> Have you ever known someone to accidentally name a C function __XYZ__ and
>> not be aware they might be stepping on the compiler's namespace?
>
> Actually it's quite common in C and C++ out there to have names starting
> with underscore even though the standard says it shouldn't be done.
>
>> Is it
>> really a problem that the compiler doesn't prevent you from using names like
>> that?
>
> Well, it is quite a common objection in C++ groups when people post code.
Really? I'm quite surprised.
--
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
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> Warp wrote:
>>> (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.)
>
>> Actually, just thinking about it a bit more, if the class returns a pointer
>> to a member variable, and you can look in the header and see that pointer is
>> in an array, then you have a well-defined way of accessing the other private
>> data in the same array.
>
> Only if you also know which array element it's pointing to. (If you know,
> then the class is, effectively, exposing the entire array.)
That's true.
--
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
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> *I* just don't see any practical advantage of having the compiler enforce
> that. You gave an example from your function library. I contend that the
> same thing could have been done with Python's level of encapsulation. It
> would be no more of an error for me (say) to change how variables that start
> with "_" work than it would be for you to change the size of the class you
> wrote.
Oh, but access rights go beyond simply restricting access from the outside.
For example, in C++ a base class can have a private member with a certain
name, and a class derived from that base class can have a private member
with the same name. There's no clash. Each class unambiguously accesses its
own member without having to explicitly specify which one with a class prefix.
The private part of the base class really is private: It doesn't even
interfere with a derived class's scope, which might have members with same
names as the base class without problems.
Also, what naming convention is used in Python for a protected member
variable or function? (In other words, a variable or function which is
accessible by a derived class but not from the outside.)
Private inheritance is not an extremely common technique in C++, but it
sometimes has its uses (one could think of private inheritance as a kind
of composition where the object itself can act as an object of either the
base or derived class). I suppose there's no such a thing as private
inheritance in Python.
> *Correct* Python code doesn't rely on "_" members remaining the same from
> one release of code to the next. Just because the compiler doesn't enforce
> it doesn't mean it's "correct".
Does the Python standard explicitly state this?
> No. Merely noting a trend. You don't always say precisely and clearly what
> you mean, and when I give counter-examples, you clarify and then act
> indignant that I addressed what you said instead of what you meant.
There's this thing called reading comprehension. Understanding what the
other wrote, in its context, rather than nitpicking on words.
> >>> 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 was talking about the memory layout of an object. There *are* no
> > guarantees about it.
> Yes, there are. There's even one I pointed out to which you said "Well, duh,
> that's the definition." Remember?
The size of an object says nothing about its layout.
You could as well claim that sizeof(double) tells you something about
how the different parts of a base-2 floating point value are laid out
inside the variable. Of course it doesn't. It just tells how much memory
the type takes, not its internal layout.
Making a guarantee about the layout of a double would be, for example,
"the most significant bit is always the sign bit".
> I do. Do you seriously tell me that knowing there isn't data from another
> object between the lowest-addressed private member and the highest-addresses
> private member isn't a guarantee about the layout of the data of a class?
Actually there's no such guarantee. If you use virtual inheritance in a
diamond inheritance situation, the common base will be shared among the
classes which were multiple-inherited from. This means that the layout
of the objects inside the most derived class will be split, rather than
being at contiguous memory locations.
> If I take the sizeof a child class, it's always going to be at least as
> large as the sizeof a parent class. If I have a class with two members of
> class X, it's going to be at least twice as large as class X, even if that
> means there are two vtable entries where one would be enough.
Sizes say nothing about the layout any more then sizeof(double) says
anything about the internal layout of a floating point number.
> If I have
> class X that inherits multiply from class A and class B, I know that I can
> take a pointer to class B and not worry that there are bits of A mixed up
> inside.
But you have no way of knowing the internal layout of B, especially if
A and B have a common base class from which they inherit virtually.
> > You don't use a debugger to resolve where the crash happens?
> That's the thing, see. When someone comes along and stomps all over the
> stack, you can't really prove what's happening very easily, even with a
> debugger.
Depends on the debugger. For example programs like valgrind and AQtime
are quite good at catching out-of-bounds accesses, memory leaks and such.
(Of course they can't catch every possible bug, but quite many.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> For example, in C++ a base class can have a private member with a certain
> name, and a class derived from that base class can have a private member
> with the same name. There's no clash.
That's cool. I imagine that helps with maintaining large code bases that
other people are inheriting from.
> Also, what naming convention is used in Python for a protected member
> variable or function?
I'm not sure, honestly.
> Private inheritance is not an extremely common technique in C++, but it
> sometimes has its uses (one could think of private inheritance as a kind
> of composition where the object itself can act as an object of either the
> base or derived class). I suppose there's no such a thing as private
> inheritance in Python.
Given there's no "private", no, I don't think you'd have "private
inheritance." :-)
> There's this thing called reading comprehension. Understanding what the
> other wrote, in its context, rather than nitpicking on words.
Yeah, let's both try to improve that. :-)
>> Yes, there are. There's even one I pointed out to which you said "Well, duh,
>> that's the definition." Remember?
>
> The size of an object says nothing about its layout.
It does. And I've given you multiple examples where it does. The very fact
that "sizeof" is defined tells you something about how you have to implement
things.
> Actually there's no such guarantee. If you use virtual inheritance in a
> diamond inheritance situation, the common base will be shared among the
> classes which were multiple-inherited from. This means that the layout
> of the objects inside the most derived class will be split, rather than
> being at contiguous memory locations.
Really? OK.
> Depends on the debugger. For example programs like valgrind and AQtime
> are quite good at catching out-of-bounds accesses, memory leaks and such.
Yeah. Now, get them to run while the graphics chips are expecting you to
respond promptly to interrupts, and without taking up more than another 3K
of memory. :-)
> (Of course they can't catch every possible bug, but quite many.)
True. Of course, I'd argue that the existence of such tools show that such
bugs are not so uncommon that they're worth disregarding. :-)
--
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
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible wrote:
> C has cpp, which (as far as I know) is very primitive and not
> Turing-complete.
It's not turing complete, but if you run it multiple times, it may be:
http://www.ioccc.org/2001/herrmann1.hint
http://www.ioccc.org/2001/herrmann1.c
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
>>> Bzzzt. You just don't know javascript very well. What object do you
>>> get when foo or bar references "this"?
>>
>> I have no idea. (And no obvious way of finding out...)
>
> Hint: It's called "window".
>
> function foo() {...}
>
> is the same as
>
> window["foo"] = Function(){...}
More precisely, a 'foo' property is added to the global object, which
happens to be "window" when the JS interpreter is hosted in a web browser.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
>>> window["foo"] = Function(){...}
>> OK. So in what way does this mean that "functions are not first-class"?
>
> I didn't say it did. I said that everything in Javascript is an object.
Correct, including functions themselves.
> There are no functions unassociated with a corresponding instance.
Functions are not associated with an instance when they are created, the
"association" is at call time.
var f = function (x) { return x; };
What instance is f associated to?
If you call f(4), 'this' inside the function body will be the global object
because of the way you *called* it. However:
var o = {};
o.f = f;
o.f(4);
This time, 'this' inside the function will be set to 'o'.
You can also do this:
var o = {};
f.call(o, 4);
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |