POV-Ray : Newsgroups : povray.off-topic : This is the sort of brokenness... : Re: This is the sort of brokenness... Server Time
6 Sep 2024 11:16:10 EDT (-0400)
  Re: This is the sort of brokenness...  
From: Darren New
Date: 18 Mar 2009 17:01:07
Message: <49c16113@news.povray.org>
Warp wrote:
>> Like, in unsafe languages, where a stray pointer can change private 
>> variables without going thru the class methods? :-)
> 
>   No. The reasoning behind data hiding in modular thinking is completely
> independent of the language used. It has to do with program design.

OK. I guess you look it as "if you bypass the documentation and access 
members not documented, I have to support your brokenness forever." I look 
at it as "if you're coding from the implementation instead of the 
documentation, you get what you deserve" combined with "don't make me debug 
my code when the bug is in your code."

>   If you expose the internal structure of a module to the outside, then
> there's a big chance that outside will start making *assumptions* about
> this internal structure.

Sure. Most of these languages (a) document what's public and what isn't, and 
(b) have a language-wide naming convention for it.  That is, after all, what 
C++'s 'private' tag is - a naming convention.

>   If this happens, then you can't change the internal implementation of
> this module without breaking existing code. For example, if you wanted
> to change the color components to floats, or you would want to pack the
> color components into one single integral value, you will most probably
> break existing code (especially probable in the latter case, as the
> amount and names of the member variables will change drastically).
> 
>   If you can design the absolutely perfect module which will never change
> its contents and will suffice for years to come, then by all means make
> all members public. Us mortals will try smarter techniques.
> 
>> C# and Java both have reflection that let you get to private members from 
>> outside.
> 
>   Thus it's one reason why the design of these languages is badly broken.

I think it's more a trade-off than you make it out to be.

>> C++ not only lets you return pointers to private members
> 
>   Only if the class itself explicitly does so. You can't get to the private
> members *from the outside*.

That's why I said it wasn't much of a breakage in my view.

> (Well, at least not without some serious hacking.)

Running off the end of an array is "serious hacking"? I wouldn't think so.

>   I don't understand what you are saying. If a class in C++ does not expose
> a member array, then you can't get to that member array from the outside,

int * p = (int *) 0x123456;
*p = 27;

Find the bug in your code that's setting that member variable to 27.

How about
// Your code...
class xyz {
   public: int[10] x;
   private int y = 0;
}

// My code
  xyz pdq;
  pdq.x[10] = 27;


>   You might be able to control your *own* code from not misusing public
> variables (and you might never make mistakes), but it's more difficult to
> control someone else.

Sure. See above examples.

>   If you need to tell someone else "don't access member variables whose
> name start with an underscore", that's just plain stupid. You should be
> able to tell that by making the *compiler* enforce it.

I agree, except for the fact that you're using C++ as an example. :) C++ has 
it's own different lack-of-modularity problems. If the compiler actually 
*enforces* that the member variables you declare private can only be changed 
by your own methods, that's great.

"don't access member variables whose name starts with an underscore" is the 
kind of rule that's enforced all through a codebase or a programming 
language. The little extra warning the compiler is going to give you is 
generally not of much benefit if someone's going to violate that rule 
anyway, IME.  In other words, if they really need to violate the privacy of 
your class, they're going to do it in C++ almost as easily as they do it in 
something like Python or LISP.  The compiler doesn't enforce the 
encapsulation in C++ - it just gives warnings when you use a variable name 
that's private. There's no enforcement at runtime, and plenty of back doors 
at compile time. Contrast with, say, C#, where you don't even know what the 
private variables are named, and you couldn't access them if you did, 
because the runtime enforces that - there, the only backdoor is the 
reflection libraries that specifically are bypassing the privacy checking 
system. Using reflection (or explicitly assigning to _private members) isn't 
any more common or more prone to abuse than ((int*)0x12345)=27; is, 
particularly because the user has to explicitly know they're violating 
encapsulation when they write the code.

Granted, if you don't *document* in a universal kind of way what's public 
and what isn't, you're leaving yourself open to abuse.

But there are a lot of people who don't want to write a ton of boilerplate 
code for a function that could be automated, so they're willing to say "if 
you use introspection  to read and write my structure over the wire, be 
aware it may change in other versions."  It's better to say "this will break 
with future versions" than to say "I'm going to write 5000 lines of 
boilerplate code to allow clients to send my values over the internet or 
into databases."

There are also a whole bunch of assumptions in your classes that someone is 
going to rely on that you're not going to be able to prevent. SimCity 
assumed memory you called free() on would still be valid until the next 
malloc(), which is obviously a bad assumption yet still has to be supported 
by the infrastructure if you expect to run simcity on later versions of the 
OS. If you store your object outside of memory or interact with any other 
objects, you're also going to have random dependencies created - someone is 
going to have to change database schemas to store your objects in a 
database, or change buffer sizes if you switch from JSON serializiation to 
XML serialization without otherwise changing your interface. There will be 
people who assume your class only invokes their getter method once, if 
that's how you first code it, and if you change to invoking it twice, they 
may very well fail out (because they're pulling the next row from a database 
for each invocation, say). Or, in short, you can't protect against bad 
programmers, and anyone half-decent isn't going to be frobbing private 
variables to start with, IME.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.