1

I'm experimenting with OOP in C, based off of this answer. I came across something I can't quite get around. Take this example:

struct foo {
    int val;
    int (*bar)(struct foo, int);
}

int foo_bar(struct foo mod, int val)
{
    mod.val = val;
}

int main(void)
{
    struct foo foo;
    foo.bar = foo_bar;
    foo.bar(foo, 8);
}

I think it would be much simpler and clearer if there was a way to use the this keyword in C:

struct foo {
    int val;
    int (*bar)(struct foo, int);
}

int foo_bar(int val)
{
    this.val = val;
}

int main(void)
{
    struct foo foo;
    foo.bar = foo_bar;
    foo.bar(8);
}

It sounds impossible, but there may be some workaround out there, a bit like OOP in C itself. Is there any way to achieve the functionality of the this keyword in Object-Oriented C?

Community
  • 1
  • 1
MD XF
  • 7,860
  • 7
  • 40
  • 71
  • 3
    Every object in C++ has access to its own address through an important pointer called "this" pointer. The ‘this’ pointer is passed as a hidden argument to all nonstatic member function calls. I think there is no need to change the behavior of c, because c is a foundation of c++, if you change the behavior of c then how can you make a difference in both language. – Sumit Gemini Dec 08 '16 at 05:01
  • If you need to use this why not just use C++? @SumitGemini said, you can pass a this pointer manually. – brianxautumn Dec 08 '16 at 05:38

1 Answers1

7

No. this keyword in C++ is a reference to the object at hand, and is actually explicitly passed to the member functions at the ABI level. Explicitly passing a pointer to the object (as the first parameter) in functions is the best equivalent in C. Note that this means

struct foo {
    int   value;
    int (*func)(struct foo *, int);
};

void foo_bar(struct foo *f, int value)
{
    f->value = value;
}

i.e. the pointer to the object is passed as the first parameter, rather than the structure itself. This makes it explicit that the object is passed by reference, and makes understanding and maintaining such code easier.


It is not sane to expect features seen in one programming language to be valid in some other programming language, even if the two are related somehow.

You see, each programming language has their own approach to problem solving, their own paradigm. Because there is no universal best paradigm possible, problems are best solved using a programming language that has the most applicable/efficient/useful paradigm. For example, you don't write a C++ program to expedite common command-line tasks; you use a shell script or other simple scripting language instead.

As a programmer, having the ability to switch from one programming language paradigm to another means you have the ability to look at a problem from different viewpoints. Looking at current software projects, the most robust, vital, and efficient ones are written by programmers who have that ability.

This is why I stated, above, that it is not sane to expect the features or paradigm of one programming language to be portable to others. You should not do that, because it is equivalent to having a single tool, and looking at all problems as if your tool at hand is the only possible tool in solving them. (If all you have is a hammer, all problems start looking like nails.) Learning, and especially learning to accept, the different paradigms in different programming languages, makes for a better programmer, better problem-solver.

Nominal Animal
  • 38,216
  • 5
  • 59
  • 86
  • As disappointing as it is... this seems like the correct answer, if C++ does indeed pass `this` to the ABI. – MD XF Dec 09 '16 at 18:57
  • 1
    @MDXF: Well, I didn't mean to disappoint you. You can verify this yourself, by simply compiling a small class to assembly (`g++ -S`), or to an object file and disassemble it (for example with `objdump -d`). (If you want proof, just say so, and I'll show and how to reproduce.) Even when a programming language provides fantastic tools to achieve stuff, there is never anything weird behind it; just hard work and good algorithms. We all stand on the shoulders of giants, and so on; even programming languages. – Nominal Animal Dec 10 '16 at 11:39
  • I'm not so much disappointed in the answer as I am in the limitations of C - I thought there may be something like a memory address or global pointer referring to the last used variable, or to the calling structure/function, something like that. But apparently not. Oh well; if C can't do it, there's no point being grumpy about it. `XD` – MD XF Dec 10 '16 at 17:29
  • @MDXF: That is a pretty weird definition of *limitation*... Because C is a low level programming language, its abstractions are relatively simple; C++ is a relatively high level programming language, with complex abstractions. These abstractions didn't grow from the hardware (as in, hardware having some feature that C did not exploit), but from the intent of approaching problems from a new viewpoint. If you want to approach problems applying that viewpoint, use a language that supports `this`! In the C paradigm, explicitly passing the pointer to the object common and *natural*. – Nominal Animal Dec 11 '16 at 09:03
  • @MDXF: TL;DR: Modify your viewpoint/paradigm, not the language. It's easier, and you get better results that way. – Nominal Animal Dec 11 '16 at 09:04