0

I'm dealing with old code, that has lots of lines like:

EST_Item_Content *contents() const { return (this == 0) ? 0 : p_contents;}

When compiling such functions, clang warns:

warning: 'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false [-Wtautological-undefined-compare]

The warning is correct, but the code is not "well-defined" and the checks are essential...

Yet, it is evident, that the check is being optimized away and the code crashes at run-time. Here is the sample gdb-session:

Program terminated with signal SIGSEGV, Segmentation fault.
Address not mapped to object.
#0  EST_Item::contents (this=0x0) at ../include/ling_class/EST_Item.h:238
238         EST_Item_Content *contents() const { return (this == 0) ? 0 : p_contents;}
(gdb) p this
$1 = (const EST_Item *) 0x0

When built without -O2, the checks remain there, and the code works as it has for years.

How do I tell clang to not optimize away these checks, which it considers redundant? There is got to be some -f-flag for it...

Mikhail T.
  • 3,043
  • 3
  • 29
  • 46
  • `this == 0` is, as the compiler mentions, kind of useless. It's probably written by the original author to protect against other bugs, that should have been solved properly rather than worked around. And as you can see from the crash, it doesn't really help. There's a bigger problem somewhere else in the code that you need to fix. – Some programmer dude Feb 21 '23 at 06:58
  • 1
    @Someprogrammerdude: Or it was written by someone who thought `this` pointers were just syntactic sugar for struct pointers, with no arbitrary restriction on them being non-NULL. Sometimes it is convenient to write code that checks for the NULL special case in the callee rather than every caller. In C++ that means you have to explicitly pass a pointer to a free function, not use a member function. If you don't know this, you might make such a function a member function anyway and write a check for `this == NULL`. – Peter Cordes Feb 21 '23 at 07:13
  • 2
    @Someprogrammerdude As someone who has inherited several >100k LOC projects littered with this checks I can say that there's a dream you can fix everything and the reality that you sometimes can't. It makes me sad to see more of this, but it's also a bit comforting knowing someone else is suffering along with me. ;) – Retired Ninja Feb 21 '23 at 07:15
  • 1
    TL:DR: With no virtual members, AFAIK the only reason that doesn't Just Work is because ISO C++ says so. (Which is a valid design choice and one that programmers should be aware of; I'm just saying I can see how it could happen, not that it's a good idea given how the C++ standard is actually written.) – Peter Cordes Feb 21 '23 at 07:15

1 Answers1

3

The flag is -fno-delete-null-pointer-checks. It is specific to such checks of this pointers against null though. It doesn't apply to all tautological comparisons.

user17732522
  • 53,019
  • 2
  • 56
  • 105