Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Emulating public and private in C structs

Name: Anonymous 2010-06-15 11:30

Consider:
foo.h:
struct Foo {
        int public_1;
        int public_2;
}
struct Foo * create_Foo ();
void bar_Foo (struct Foo*);
/* etc */

foo.c:
#include "foo.h"
struct Foo_private {
        struct Foo foo; /* ??? */
        int private_1;
        int private_2;
}
struct Foo * create_Foo (void) {
        return malloc (sizeof(Foo_private));
}
void bar_Foo (struct Foo *foo) {
        Foo_private *foo_p = (Foo_private*) foo; /* ??? */
        /* do whatever with foo_p->private_1 and foo_p->private_2 */
}

Is there anything wrong with this? I'm dubious about the lines commented with ???. I don't want to write getters and setters for the 'public' stuff.

Name: Anonymous 2010-06-15 11:33

structs are NOT supposed to be used this way

Name: Anonymous 2010-06-15 11:33

That's... what?

Name: Anonymous 2010-06-15 11:39

Yes this is doable. This is how the sockaddr structures work in unix sockets

Name: Anonymous 2010-06-15 11:41

I think I understand what this code was trying to go for but I'm not sure "private" is the word for it.  Essentially, you are hoping that casting a struct Foo into a [/code]struct Foo_private gives you temporary access to [code]private_1 and private_2 but, after it casts back to a normal struct Foo, you can no longer access data in private_1 and private_2?

Name: Anonymous 2010-06-15 11:42

>>5
BBCode failure.  That'll teach me to copy-paste closing tags.

Name: Anonymous 2010-06-15 11:51

>>5
Kind of the other way around. When using a Foo, you're never allowed access to private_1 and private_2, except through bar_Foo() (and even then you still don't know that they exist). But you can alter public_1 and public_2 willy-nilly.

The problem is if I wanted an array of struct Foos, it would clobber private_1 and private_2. I looked up sockaddr from >>4 and it seems that having a char private_stuff[8] or similar at the end of struct Foo would solve that.
... I guess I could do that.
Also I'm aware that I'm missing a lot of `struct.'

Name: Anonymous 2010-06-15 11:54

What's wrong with a nested struct with private fields?
struct Foo {
        int public_1;
        int public_2;
        struct Foo_private *private;
}

Name: Anonymous 2010-06-15 11:58

>>8
Multiple mallocs and cyclic dependency

Name: Anonymous 2010-06-15 12:05

>>8
[code](foo->private)->private_1[-/code] is accessible from anywhere as long as you know it exists.  Even if you know it exists, a normal private variable can not be affected outside of a certain scope.

OP goes one step further: the "private" value is virtually inaccessible except if you make a cast.

Name: Anonymous 2010-06-15 19:01

Just don't access the private members outside foo.c. You can catch mistakes with

struct Foo {
        int public_1;
        int public_2;
#ifndef HIDE_PRIVATES
        int private_1;
        int private_2;
#endif
};


and gcc -DHIDE_PRIVATES -fsyntax-only.

Name: Anonymous 2010-06-15 20:46

>>11
#ifdef IN_FOO.C would be better.

Name: Anonymous 2010-06-15 21:24

>>11
I think that misses the entire point of private variables. They are private because we don't trust anyone but ourselves to access them. If you "trust" other modules enough to use this method (you aren't actually hiding anything- just testing that it can be hidden in future through some means) the entire exercise is pointless.

Name: Anonymous 2010-06-15 21:45

"private variables" is pointless ENTERPRISE BULLSHITE anyway.

Name: Anonymous 2010-06-15 22:07

>>13
You don't have a clue what the actual reasoning behind private variables is.

Name: Anonymous 2010-06-15 22:52

>>12
Any way is fine, but be careful to only syntax check. If you compile then you have a different struct Foo outside foo.c than inside foo.c, which is a subtle bug waiting to bite.

>>13
If the client abuses the interface then it's his own problem. C simply requires this kind of trust by its design. Trying to idiot-proof your code is an uphill battle against the language. For example, how can you protect against someone passing (void *)0xDEADBEEF to your function?

Name: Anonymous 2010-06-15 22:55

>>13
Private variables protect from accidental access, never from intentional tampering. That would be a terribly dumb thing to try to prevent.

Name: Anonymous 2010-06-15 22:56

True private variables are pointless. I prefer exported/unexported variables. Exported symbols are part of the public interface. If you use unexported symbols, it's your own damn fault if something messes up. It's not like you can't access privates in SEPPLES and other languages through various direct memory access tricks.

Name: Anonymous 2010-06-15 23:16

>>15
A well reasoned and coherent argument! Excellent points.
>>16,17
That [intentional tampering] would be a terribly dumb thing to try to prevent
In C, yes, that is my point. There is no information being hidden with this method, so there is no point making it private. Flipping a macro for a syntax check is precisely as private as manually choosing not to externally access it, i.e.: not private at all.

Name: Anonymous 2010-06-15 23:49

>>19
Not so! private was a great choice of words and a good metaphor. With effort, and sometimes a trivial amount, one can invade on another's privacy. But we've all made a social agreement to respect privacy; all it takes is a humble token, like a window curtain, to remind us of this. The curtain is just cloth, but it does an excellent job of affording us privacy, because it asserts our intent. That way, if we're able to detect it, we can be certain in knowing that our privacy is violated -- otherwise, any access we didn't think to deny (but would regret later) might accidentally intrude upon us -- and with no ill will from the innocent onlooker! How foolish of us, that we didn't draw the curtain when we had the chance!

Name: Anonymous 2010-06-17 5:56

>>1
Well there doesn't seem to be anything directly wrong with this, as long as people can't do anything useful with a stack-allocated Foo or an array of Foo. A stack-allocation or array-allocation won't have your private data attached to it, so an attempt to access it would be out of bounds.

C99 does provide the necessary exceptions to the strict-aliasing rules to allow you to cast back and forth between Foo and Foo_private. So this is standards compliant, providing it is used correctly.

Honestly you are *much* better off just hiding the whole struct and providing some accessor/mutator functions for the fields you want public. This way your struct cannot be allocated by the developers using it, and it is much better future-proofed; you can safely add extra behaviour to your accessors/mutators later on or completely change the internal implementation and leave these as wrappers. In general you should rarely expose the contents of your structs in C.

Name: Anonymous 2010-06-17 7:30

Do YOUR children have access to your private parts? protected? What about your friends? C++ makes it all so clear. Stroustrup is a genius. Nice job OP.

Name: Anonymous 2010-06-17 7:31

>>19
In C, yes, that is my point.
No, not just in C, in every language. Private variables protect a programmer from accidental mistakes; they aren't intended to turn the language itself into an obstacle. You don't seem to grasp this.

Name: Anonymous 2010-06-17 15:46

>>23
Many languages or virtual machines do provide very real runtime protection against encapsulation violation. This is useful in creating secure execution environments without having to create separate processes with their own virtual memory and so forth. Java is the canonical example here.

C++ doesn't (among other languages, such as Objective-C) because it trades off security for speed.

Name: Anonymous 2010-06-17 15:48

>>23
Also, would you please not sage? This is one of the few interesting topics here, and bumping them is one of the few ways we can avoid being overrun by spam/trolling. Please folks, reserve your sage for off-topic threads.

Name: Anonymous 2010-06-17 15:57

>>24
Java allows for modification of private fields as well, through reflection. It makes it more difficult, because it's a language designed for and by idiots, but that's hardly news.

secure execution environments
Cute but meaningless.

>>25
Your definition of ``interesting'' differs from mine. It's better than ancient worthless threads being bumped, or the idiot spam threads created to discredit Xarn, but it's still almost /pr/-level nonsense.

Name: Anonymous 2010-06-17 15:59

>>24
Secure against what? I can't think of any use for checking for encapsulation violations that at runtime if the language itself doesn't allow them. What justifies the added complexity and performance penalty? Looks like the effort would be better spent on securing the OS itself than the VM that's running on it.

Name: Anonymous 2010-06-17 16:06

>>25
learn to sage or go back to /pr/.

Name: Anonymous 2010-06-17 16:13

>>28
Learn how capitalisation works or go back to the imageboards.

Name: Anonymous 2010-06-17 16:13

I'm new here and what is /pr/? Thank you for your time.

Name: Anonymous 2010-06-17 16:19

>>29
go back to france.

>>30
a miserable pile of php, FIOC, and java.

Name: Anonymous 2010-06-17 16:24

>>31
You still think the Franks were French, then?

Name: Anonymous 2010-06-17 16:25

>>31
You don't belong on /prog/.

Name: Anonymous 2010-06-17 16:38

>>32
The name France comes from Latin Francia, which literally means "land of the Franks". Originally it applied to the whole Frankish Empire, extending from southern France to eastern Germany.

Name: Anonymous 2010-06-17 16:41

>>26
Java allows for modification of private fields as well, through reflection. It makes it more difficult, because it's a language designed for and by idiots, but that's hardly news.
Only under certain conditions. An active security manager can reject all attempts at reflection; this allows truly secure code execution.

>>27
Secure against what? I can't think of any use for checking for encapsulation violations that at runtime if the language itself doesn't allow them. What justifies the added complexity and performance penalty?
Duh, if the language doesn't allow encapsulation violation, then there is a runtime cost to accessor/mutator functions; these can't be inlined at compile-time. Even though the VM can inline such calls, it still has to be done at runtime, or at least in some preparation step somewhere on the user's hardware, otherwise the binary could be modified by an attacker after compilation. The VM has to check for encapsulation violations at load time to provide a secure environment before any such optimizations can be performed. This is why desktop Java apps take so long to start up and wind up in performance, and this is why J2ME apps take so long to install on device.

Name: Anonymous 2010-06-17 16:42

>>34
And in Byzantium ``Frank'' applied to every person born west of Constantinople. So what? All you've done is demonstrate a profound ignorance of history, and an inability even to use Wikipedia effectively.

Name: Anonymous 2010-06-17 16:47

>>35
You still haven't explained what ``secure'' even means in this context, and what is gained by it. It's clear you've drunk the Kool-Aid without pausing to consider what it was you were actually consuming.

Name: Anonymous 2010-06-17 16:52

>>35
So I can distribute a symmetrical encryption key for use in digital signing in Java binaries? Brilliant!

Name: Anonymous 2010-06-17 17:01

>>36
the binary could be modified by an attacker after compilation.
If the attacker has the means to do so, then he's already in control of the system running the VM. This is what I don't understand. No amount of VM trickery will save you in that situation.

>>37
You have problems with reading comprehension.

Name: Anonymous 2010-06-17 17:03

>>39
Expert post referencing, there.
But are you saying you define ``secure'' specifically as meaning ``applications are unable to access private variables''? Because then you're just going around in circles.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List