Agreed, one of the biggest design mistakes in the OOP syntax of C++ (and Java, for that matter) was not making `this` mandatory when referring to instance members.
C++ and Java went for the "objects as static closures" route, where it doesn't make any sense to have a `this`. Or, they made them superficially look like static closures, which in hindsight was probably not the best idea. Anyway, Java lets you use explicit `this`, I don't recall whether C++ makes it into a footgun or not.
Both languages let you use explicit `this` but don’t mandate it. The “static closure” approach is great. I don’t like having to explicitly pass `this` as a parameter to every method call as in the OP (or worse, the confusing Python approach of forcing `self` to be explicitly written in every non-static method signature but having it be implicitly passed during method calls).
What I don’t like is being able to reference instance members without `this`, e.g.
void foo() {
int x = bar + 1; // should be illegal: it can be hard to distinguish if `bar` is a local variable versus an instance member
int y = this->bar + 1; // disambiguation is good
}
> int x = bar + 1; // should be illegal: it can be hard to distinguish if `bar` is a local variable versus an instance member
If it was this->bar it could be a member, it could also be a static variable. A bar on its own could be local or it could be in any of the enclosing scopes or namespaces. Forcing "this" to be explicit doesn't make the code any clearer on its own.
The guy was referring to the explicit case where bar is a member variable. The cases where it is in the local scope under scoping rules or the global scope are not really an issue, since you can check the function definition to find if it is local. In the case that it is not in the function definition, then it is in the global scope in C. If implicit this were not done in C++, that would also be the case in C++, provided you do the sane thing and use the std namespace for everything. Just thinking about the headaches namespaces could cause when looking for such definitions with cscope gives me yet another reason to stay away from C++ whenever possible.
that's not really true - unlike a regular pointer, `this` is not allowed to be null, thus removing `if(this == nullptr)` is always a valid optimization to do.
This is undefined behavior in my understanding, it just happens to work until it doesn't.
I wouldn't be surprised if any null check against this would be erased by the optimizer for example as the parent comment mentioned. Sanitizers might check for null this too.
/app/example.cpp:10:6: runtime error: member call on null pointer of type 'Foo'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /app/example.cpp:10:6
/app/example.cpp:3:8: runtime error: member call on null pointer of type 'Foo *'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /app/example.cpp:3:8
That's undefined behavior. It's "allowed" in the sense of "yes it's possible to write, compile and run that code", but the language makes no guarantees about what the results will be. So maybe not the most useful definition of "allowed".
Only in so much that this being null is UB, but in the real world it very much can be null and programs will sometimes crash deep inside methods called on nullptr.
Supporting an explicit this is required to be able to access the member variable when a local variable hides it under scoping rules. As another person replied, C++ does indeed have an implicit this.