Eric Sosman
9/13/2011 12:17:00 AM
On 9/12/2011 3:01 PM, Ben Bacarisse wrote:
> Fred<fred.l.kleinschmidt@boeing.com> writes:
>
>> On Sep 11, 2:58 pm, Ben Bacarisse<ben.use...@bsb.me.uk> wrote:
>>> Ð?акÑим Фомин<ma...@maxim-fomin.ru> writes:
>>>> I want to hide several fields within structure from "client" code. Can
>>>> I use following (just example):
>>>
>>>> - declare struct X { int visible; }; in "export.h" and several
>>>> functions, which take struct X as an argument;
>>>> - "export.h" is included by client code;
>>>> - declare struct X { int visible; int hidden; }; in "private.h";
>>>> - "private.h" is included in .c file which contains definitions of
>>>> functions which work with struct X
>>>
>>> Just to clarify: you mean pointers to these structs will be passed, yes?
>>> You don't say so but without passing pointers it is certain to fail so
>>> it seems like a reasonable assumption.
>>>
>>>> Thus, when mentioned functions process struct X, they may access to
>>>> hidden integer, however external code even doesn't suspect that there
>>>> is one.
>>>
>>>> The first issue of this technique is that client code cannot hold
>>>> allocation.
>>>
>>> If the allocation is "behind the wall" so to speak, have you considered:
>>>
>>> struct X { int visible; };
>>>
>>> struct Y { struct X x; int hidden; };
>>>
>>> The allocator makes a struct Y but passes&Y.x to the client. When the
>>> client passes&Y.x back to the other side of the wall, the conversion
>>> from struct X * back to struct Y * is certain to work.
>
>> And what happens if one declares an array of X's, then tries to
>> access
>> x[1].visible ?
>
> Exactly what you'd expect happens. I know that was a rhetorical
> question but I'm not sure what else to say. Yes, arrays don't work with
> this scheme, but they won't work with any scheme where the size of the
> actual allocation is hidden from the "client" side. Presumably the OP
> accepts that restriction and would use and array of pointers instead.
This is one reason the "visible" part is often entirely empty,
so the caller gets a pointer to a completely opaque object (formally,
an "incomplete type") and cannot possibly create a free-standing
instance on his own.
True, given a `struct X*' the caller cannot then access its
"visible" member(s). Instead of just peeking and poking at those
elements the caller must resort to accessor functions provided by
the library, "getters and setters" as our O-O friends might say.
That's a disadvantage, but usually not a crippling disadvantage.
--
Eric Sosman
esosman@ieee-dot-org.invalid