Re: A C++ Whishlist

From: Andre Kostur (nntpspam_at_kostur.net)
Date: 03/16/04


Date: Tue, 16 Mar 2004 21:27:14 GMT

bichir@covad.net (Ram Firestone) wrote in
news:693c5df1.0403161218.4bd644dd@posting.google.com:

> Andre Kostur <nntpspam@kostur.net> wrote in message
> news:<Xns94AE46C907DF4nntpspamkosturnet@207.35.177.135>...
>> I doubt they explicitly implement "call through NULL" now (ie:
>> there's a feature point on some list of things to implement). What I
>> think is much more likely is that it is an artifact of how normal
>> call dispatch is being implemented.
>
> I agree. It's not explicitly implemented. It's just typically the most
> efficient way to do it.

But that does mean that as a compiler writer, I'm allowed to implement
all function calls via a pointer to go through a vtable-like mechanism.
Both virtual and non-virtual functions.
 
>> You invoke undefined behaviour and the compiler is free to do as it
>> wishes. You would be negligent as a programmer to write anything
>> that calls a member function via a NULL pointer.
>>
>
> Let's get something strait. We are talking about a change here. That's
> the whole point of this thread. I know the current situation.

Yes, we are talking about a change. You're suggesting a change, and I'm
posing counterarguments to the change.

>> > the compiler somehow wastes time and code checking this == NULL,
>> > you
>>
>> (compiler time is cheap in the grand scheme of things.... I'd rather
>> use compiler time, then have my program crash)
>>
>
> Sorry I should have explained myself better. I was referring to the
> compiler adding run time code to check for NULL.

Now everybody else has to pay the price of comparing a pointer against 0
every time a method is called _just in case_ you happen to be passing a
NULL? That kinda goes against the general C++ principle of not paying
for something you don't use.
 
>> > still get some sort of fault. Now let's assume we explicitly allow
>>
>> Actually, you can't even guarantee you'll get a fault. That's part
>> of undefined behaviour... the compiler/program can do whatever it
>> wants, including behaving how you think it should work. Problem is,
>> as soon as your program is ported to a different platform, or
>> different compiler, or different version of the same compiler, or the
>> planets come into alignment, that behaviour may change. It's
>> undefined.
>>
>
> Ok granted, there is not gaurantee you'll get a fault. I will modify
> my statement. There is a guarantee that NULL may not hold a valid
> class instance. If your program is broken it's still broken. If it
> works it still works. No change.
>
>>
>> You are now _expected_ to be able to handle calls through NULL. If
>> you don't, you would be negligent as a programmer. There's other,
>> more subtle implications, IMHO.
>>
>
> No you arn't. There is no expectation to handle call though NULL if
> you don't want to, just like there is no expectation that you should
> handle every possible calling error in any function. I think this is
> the main point of contention. I look at the this pointer as just
> another parameter. I certainly don't check for NULL on all my function
> paramters and I don't check this == NULL either. What's the
> difference?

Not to sound nasty, but that's sloppy programming. If I don't expect a
NULL pointer, I would be using a reference (barring certain less common
cases).

>> Because you also get to assume that your program is well-formed,
>> which means that it doesn't invoke undefined behaviour, such as
>> dereferencing NULL pointers, or calling member functions via a NULL
>> pointer. It's not undefined behaviour until you invoke a member
>> function via a NULL pointer.
>
> Calling a non-virtual member through a NULL pointer does mean you have
> to dereference it.

Depends on how the compiler writer chooses to implement function calls
through a pointer. See the hypothetical compiler I mentioned above.

>> > Obviously I should probably not use undefined behavior but since we
>> > are talking about additions this is what I would like to see.
>> > Please explain to me how any current portable C++ program would be
>> > broken by this addition? Also I don't want a static function. It
>> > may or may not get a NULL this pointer. That doesn't mean it always
>> > get's a NULL this pointer.
>>
>> How about:
>>
>> class Base { virtual fn() = 0; };
>> class Derived : public Base { virtual fn() { cout << "der" << endl;
>> }; };
>>
>> int main()
>> {
>> Base * bp = new Derived;
>> Base * bp2 = 0;
>>
>> bp->fn();
>> bp2->fn();
>> }
>>
>> Also assume that the platform it happens to be running on performs a
>> hardware trap on attempting to dereference a NULL pointer and _will_
>> melt your CPU (recall that dereferencing a NULL pointer is also
>> undefined behaviour, thus this is perfectly legitimate behaviour).
>> Note the pure virtual base class, it will never be instantiated
>> directly, but will always be inherited from.
>>
>
> I said non-virtual in my first post so this doesn't apply. For
> non-virtual members my change would imply that they are not referenced
> upon call. This should be easy to do since there is no reason to
> reference them outside doing some sort of explicit check.

So why have different rules for virtual vs. non-virtual? And then in
future when an implementation changes from non-virtual to virtual, you're
wasting time checking for a NULL pointer that will never arrive (in a
well-formed program), or when it changes from virtual to non-virtual you
now have to worry about getting a NULL this pointer since now it's legal.

Also, that also means that some member functions of a class may be called
via a NULL pointer, and some can't
 
>> PS: assume all references to a "NULL pointer" refer to a pointer
>> which has been assigned 0. Strictly speaking, there is no such thing
>> as a NULL pointer.
>
> Yes I know.

That was just to circumvent people (not you...) from possibly complaining
about "NULL pointer"... :)

I guess the overriding question would be is what's the tangible benefit
of being able to call a method via a NULL pointer? It can't access any
member data (it has no object upon which to work).... So why invoke via
a NULL pointer when a static member would give you the same behaviour,
without the possibility of you trying to use the this pointer which may
not be valid?



Relevant Pages

  • Re: Casting of pointer to member functions
    ... cast it back before any usage. ... The example above will compile only if /ymg compiler switch ... the bits that pointer is ... calling a member function through such pointer is ...
    (microsoft.public.vc.language)
  • Re: A C++ Whishlist
    ... > You invoke undefined behaviour and the compiler is free to do as it ... > calls a member function via a NULL pointer. ... > means that it doesn't invoke undefined behaviour, ... > undefined behaviour until you invoke a member function via a NULL ...
    (comp.lang.cpp)
  • Re: Mex Overflow Error Using Free Borland Compiler
    ... >>>would clean up a lot of code by eliminating the pointer dereferences. ... >>>guaranteed by the standard and should not be relied on. ... >>>You can try the GNU C compiler available on mingw or cygwin. ... >>>the Constraints are then both operands shall have arithmetic type. ...
    (comp.soft-sys.matlab)
  • Re: Weird pointer error
    ... > int main{ ... and you let a pointer to non-const char point to it. ... even on the same system with different compiler settings or a newer ... something specific happens when you invoke undefined behaviour. ...
    (comp.lang.cpp)
  • Re: Anybody here endure C/Cpp? (.h to .inc conversion)
    ... Pascal or Stdcall convention... ... "PFNGLPOINTPARAMETERFEXTPROC" to be a type that's a pointer to a function ... DWORD, using a 32-bit compiler, with an address in it...adding the ... this is working on the premise that OpenGL does it like most others ...
    (alt.lang.asm)