1

I'm using C in a minimal, efficient OOP style to build a game engine. A problem I've begun to face as the engine code settles is my (erstwhile) choice to use this. For example, I have:

void Engine_initialise(Engine * this);

void Window_terminate(Window * this);

Window * this contains a reference to the singleton Engine. Now, let's say I reference this Engine member from both Engine_initialise(..) and Window_terminate(..);. In the former it will be this->member, yet in the latter it will be (window->)engine->member.

This inconsistency annoys me; if it is the same, it should look the same. And as I work purely in a text editor without IDE, I want a single find-replace across all files, instead of multiple find-replaces.

Let's consider another example, where there isn't only one argument of the given type.

Blob_compare(Blob * this, Blob * that);

vs.

Blob_compare(Blob * blob, Blob * blobOther); //or blob1 and blob2, or whatever

...in spite of my preference for losing this, the former looks better as it is descriptive and concise.

Question: Are there any particularly strong arguments for continuing to use this as the name of current object instance in my various functions? I'm thinking of replacing all this with engine (or similar). I would like to settle on a coding standard in this regard, for all C code.

I am asking about the usefulness of this as the primary function argument; the names of other parameters of similar type are not of major importance here in spite of my second example. To me it seems sensible, if the function is prefixed with Blob_, to assume that blob refers to the current instance. And no, I really don't care one iota about renaming types - these are well fixed.

1
  • 1
    Why do you need the parameter to always be called the same thing or even have some kind of "standard". As a counterexample, look at the docs for FILE-based functions in the standard library. The tendency is to name the FILE parameters stream. I.e. you don't have to write FILE *file in the prototype to make it clear how to use your functions.
    – Brandin
    Aug 14, 2015 at 20:13

2 Answers 2

7

If they are supposed to be singletons, and you really want to do things in your (conceptual) style, you might want to use Context object.

(First and foremost: apologies. C is not my native language; C++ is.)

Basically,

struct Context
{
    Engine * engine;
    Window * window;
    // any other things that are considered singletons 
    // according to your conceptual style
};

void Engine_initialize(Context * context);
void Window_terminate(Context * context);

For reference, take a look at jpeglib and libtiff on their use of some root level objects which contain pointers to all other relevant stuff needed by the code.


As a sidenote, using this as the identifier name in C code (and header files) will create griefs for people who try to integrate your C code into C++ projects. See this question for opinions on this.

3
  • Another reason against using this in C code pretty much topples it for me. Thanks rwong. I will wait a while for other answers but this is looking likely.
    – Engineer
    Aug 14, 2015 at 10:59
  • I was just thinking the same thing about C++ integration, what a nightmare since "this" is a keyword. Aug 15, 2015 at 6:36
  • 1
    Why would you want to give Engine_initialize() understanding of a structure beyond Engine? If a Context has an Engine, there should be a Context_initialize() that calls Engine_initialize().
    – Blrfl
    Aug 27, 2015 at 10:16
2

I would suggest to avoid using this as a formal name in C, because this is a C++ keyword. You could use e.g. self (or me or recv, or ipse -it is self in Latin) instead of this

If you code your C code without using C++ keywords, you are much more likely to be able to use your code with a C++ compiler.

In particular, quite often a C header file foo.h (with some static inline functions) which does not use any C++ keyword is very likely to be usable from a C++ program (perhaps by surrounding the #include "foo.h" directive with extern "C" { & };, because C++ has been (originally) designed to be upward compatible with C (this is slightly less true with C++11 and C11).

1
  • 2
    self is already taken by Objective-C, which, like C++, expands on C. So self has the same problem as this. For that reason, me looks like the smartest choice to me. Aug 14, 2015 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.