Creating and using a .this pointer in C language structs
-
If you need me, I'll be busy adding a new field to all of my C structs.
-
This blog post contains examples of how to create a this pointer in C. You may know "this.xxxx" is a C++ attribute of objects. Well like many things you can emulate it in C because C is far more flexible without the bloating that object oriented languages provide for lazy programmers to make mistakes.
I can already tell we're in for some gold.
Of course, in order to emulate in C it requires more knowledge/experience than the average starting programmer can do. And as websites develop bit rot for older technology these things get lost unless others decide to pick up the challenge to maintain them. I do not claim to be the first to do this, I am sure it's been done, but I am the one making a clear explanation and re-introducing it as it were.
"I'm not sure if other cavemen have meticulously carved equally square wheels before I did, but I'm going to claim this square wheel carving as my own, so tough shit!"
I tried to post to stack exchange but I do not meet the process nazi's interpretation of a good question so I won't bother providing them my help. I would rather be helpful than process-correct and I don't get paid to educate so I stick to the facts without superfluity in a non-educational idiom.
I'm curious to see what the SE question looked like. For once, their passive-aggressive nerd sniping might be amusing.
-
Well like many things you can emulate it in C because C is far more flexible without the bloating that object oriented languages provide for lazy programmers to make mistakes.
…
I follow the unix philosophy writing understandable code and leaving optimization as another step
-
Pointers take time to understand and remember that pointers give a value or an address, not an array, when accessed. That's why a pointer to element with offset indexing leads to another pointed-to element. An array is guaranteed for your program's sake (as far as it can see) to be a contiguous length of memory of type.
The struct is a value when accessed one way, it is an address when accessed the other.
I don't like the *( a + i).element method of writing C structs because it is a babyish technique taught by naive professors that have never dared to make more complicated nested code. Some claim it is faster and I don't dispute that but I doubt they've tried harder because they stop teaching at the semester end.
stick it to da man
-
He should next invent the
container_of
trick:
-
I'm not really a C (or related languages) person. Do I have this right? He's creating a "this" field which has the address of the struct, but the only way he uses it is in lines like
a->neighbours[a->neighbour_number] = (struct cca_t * )b->this;
which could just as easily - well, actually more easily - be written
a->neighbours[a->neighbour_number] = b;
The point of "this" is for class methods and the like to access members of the object, right? So it's completely useless in C where you don't have any of those things?
-
@Scarlet_Manuka said in Creating and using a .this pointer in C language structs:
'm not really a C (or related languages) person. Do I have this right?
Yes, you've got it.
-
this
is always a function argument in every language I've ever seen. It's never a field of a struct.
-
@Scarlet_Manuka said in Creating and using a .this pointer in C language structs:
completely useless
Oh don't be so babyish. Once you start writing nested programs, then you'll see.
-
Nested programs? Move into the fourth dimension, man. Start using Bosco Quadrany and
one_of_these
pointers.
-
There was a time in the mid to late 1980s when some pop-tech magazine like Byte or DDJ had an article about doing something like this every four months or so. It was a bad idea then, too.
OTOH, you still get new OO implementations for Scheme on nearly a weekly basis, which is amazing considering that most programmers would rather eat a pistol than work in Lisp (the exceptions. like me, seem to spend more time writing OO libraries than applications). While I get that it's a rite of passage thing - I did it too, after all - that doesn't mean your special-snowflake implementation is worth sharing.
Filed Under: and the Academy Award for Best Leading Hypocrite goes to. ..
-
Hilarious. Complains about bloat and then bloats things with an utterly useless pointer to itself. :double_face_palm.c:
-
@ScholRLEA said in Creating and using a .this pointer in C language structs:
spend more time writing OO libraries than applications
Try writing the libraries so that they support some interesting applications. Building a whole bunch of stuff preemptively just in case you need it… total time sink. It's more fun to make things you can use, and that's especially true when you can use them immediately.
If you get successful to the point where other people write your libraries for you, that's even better.
-
@Scarlet_Manuka said in Creating and using a .this pointer in C language structs:
So it's completely useless in C where you don't have any of those things?
You could shorten that to just “So it's completely useless”. The only way to get the value is to have the value already.
The silly thing is that he missed doing something which would have actually made sense for “sort-of doing OO in C”: there's no reference to a descriptor of the type in the structure (i.e., basically a vtable). Which means that he can't do dynamic dispatch, inheritance, introspection or anything else useful like that. IOW, he's a moron straight from central casting, and it is evident in both his “technical contributions” and in the whiny stupidity in the explanatory text; DO NOT HIRE.
-
@ScholRLEA said in Creating and using a .this pointer in C language structs:
most programmers would rather eat a pistol than work in Lisp (the exceptions. like me, seem to spend more time writing OO libraries than applications)
Relevant entry from quote file:
I find it weird that people who use* the world's most extensible programming language have these idiotic discussions on the library parts of the standard. I suppose that these are the same people who call the factory to complain when their 21-speed road bike arrived with the chain positioned on cogs 2-7 -- the rest just learn how to shift gears and start biking.
*Of course, it frequently turns out that the people who initiate these discussions do not actually program in Lisp. So why are they taken seriously? This is a great mystery.
-
And if anyone is still wondering why C (preferably with its programmers) should die, there's another point in favor.
-
I think we have found an example case of the Expert Beginner.
-
You don't understand the depth of this, shallow C monkeys! This is self-documenting code. It allows introspection! What it is missing is also a class field, where you can record the type of the struct. Then you could figure out the memory address and the type of object by just dereferencing the first two fields of any pointer. The important bit is that you have this on all structs, so you can safely examine all pointers you're given. For starters, this would allow you to return any type of object from a function. The calling function could then figure out what to do with the object received based on its type.
It's a shame that popular C libraries do not use this scheme, it would simplify so much! Functions would be free to return new object types as they are being extended! But the backwater C of mediocrity is actively working against improvements because they are too entrenched in their own habits.
-
@gleemonk ...even if you did add a type field, the
.this
pointer is still literally useless:
-
@anotherusername said in Creating and using a .this pointer in C language structs:
the .this pointer is still literally useless
Would it be better if you printed it on a piece of paper, put it on a wooden table, and then stood on top of it?
-
@dkf said in Creating and using a .this pointer in C language structs:
@anotherusername said in Creating and using a .this pointer in C language structs:
the .this pointer is still literally useless
Would it be better if you printed it on a piece of paper, put it on a wooden table, and then stood on top of it?
No. You need to go to a mall. Steal their map. Take it somewhere else and table/printer/etc. Now you have proof the you-are-here is WRONG!
-
@anotherusername Might be useful in an embedded base class to get back to the originally allocated object (
Dog
extendsAnimal
, in an allocatedDog
theAnimal
object has athis
member pointing back toDog
).
-
@PleegWat Nope. In any sane extension scheme, it's the compiler's job to keep track of all that stuff and the extended Dog will simply contain all the members of the base Animal at the same offsets. Any design where inheritance works by converting single objects into linked pairs - especially if that implementation needs to be visible to the coder - is crazy talk.
The only conceivable justification for such a design would be to allow multiple Dogs to share read-only members of a singleton parent Animal, in which case a single pointer to Dog inside Animal would be of no use whatsoever anyway.
-
@flabdablet said in Creating and using a .this pointer in C language structs:
In any sane extension scheme, it's the compiler's job
In plain C, the compiler won't know about it.
I've done some object-like C stuff, but we don't have a full object model, and I don't see need to implement one.
-
@PleegWat said in Creating and using a .this pointer in C language structs:
In plain C, the compiler won't know about it.
In plain C, the only sane way to do extension still involves embedding the parent struct's members inside the derived struct. Only a mad person would implement what is conceptually a single object as multiple blocks of memory with links.
-
@flabdablet said in Creating and using a .this pointer in C language structs:
In any sane extension scheme, it's the compiler's job to keep track of all that stuff and the extended Dog will simply contain all the members of the base Animal at the same offsets.
The usual way to do that in C is to put the superclass
struct
literally as the first element of the subclassstruct
.struct Superclass { long abc; double def; char *ghi; }; struct Subclass { struct Superclass super; void *jkl; int mno; };
That works, and it also works if the two are mixed together in a
union
. Indeed, if it didn't there'd be so much code that would immediately fail horribly that I'm certain it will continue to work for as long as people continue to use C. (Some compilers — those that are new enough to follow C11 — allow anonymous structure members which can make it a bit neater, but I'm not convinced they're a big help.)
-
@dkf Yes. One could also abuse the macro preprocessor to get rid of the need to do
theDog->super.abc
instead oftheDog->abc
all over the place, but the benefit probably isn't worth the cost.
-
@flabdablet said in Creating and using a .this pointer in C language structs:
the benefit probably isn't worth the cost
It's sometimes useful when dealing with a particularly elaborate structure with multiple layers of mixed structs and unions (and sometimes that's even the right choice of data structure!) but when I do that I keep the #def-ery to as small a piece of code as possible.
-
@dcon said in Creating and using a .this pointer in C language structs:
No. You need to go to a mall. Steal their map. Take it somewhere else and table/printer/etc. Now you have proof the you-are-here is WRONG!
You see how having a
this
pointer also helps with detecting your objects were copied without proper procedure?
-
@gleemonk said in Creating and using a .this pointer in C language structs:
You see how having a this pointer also helps with detecting your objects were copied without proper procedure?
In that case, you need a
that
pointer…JSRF - Like This Like That – 02:50
— TechnoHeroine