dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: [RESOLVED] Why is ((foo*)NULL)->bar(); undefined?

  1. #1
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    [RESOLVED] Why is ((foo*)NULL)->bar(); undefined?

    I've seen code to this effect appear twice on this forum in the last couple of days. Both times the response was that the result is undefined.
    Code:
    ((foo*)NULL)->bar(); // where bar is not static or virtual
    I've skimmed through the standard, but found nothing yet.
    I'm intending printing off a copy and looking in more depth tonight.

    My question:
    Is the result undefined because the standard explicitly states that it is, or does the standard simply fail to address the issue?

    Thanks very much for you time.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  2. #2
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Why is ((foo*)NULL)->bar(); undefined?

    Dereferencing a null pointer yeilds undefined behaviour, in my 2005 draft of the standard there is a reference to this in section 1.9 (program execution):

    4. Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing
    the null pointer). [ Note: this International Standard imposes no requirements on the behavior of programs that
    contain undefined behavior. —end note ]

  3. #3
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Why is ((foo*)NULL)->bar(); undefined?

    It's undefined because it is calling a member function on an object that does not exist!

    What it is saying is essentially "At address NULL pretend we have an instance of the 'foo' class and call the member function 'bar' in it.

    If the function 'bar' accesses no member variables it may work. Or it may not.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  4. #4
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Why is ((foo*)NULL)->bar(); undefined?

    Because the implicit "this" pointer within foo::bar would be null and any attempt to access a member would imply dereferencing a null pointer, which is undefined behaviour.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  5. #5
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: Why is ((foo*)NULL)->bar(); undefined?

    Thanks PredicateNormative that's getting close to what I'm looking for.

    I'm interested in the standard rather than the semantics of the given code. I suppose my reason for asking could be better encapsulated in the following program:

    Code:
    #include <iostream>
    
    class foo {
        int bar() {
            if (this == 0) return 0;
            else return 1;
        }
    }
    
    int main(int argC, char ** argV) {
        std::cout << ((foo *) 0)->bar();
        return 0;
    }
    It's clear that most compilers will allow this and most of them will simply print 0 and terminate with exit code 0. But the implication in other threads is that the result is undifined.

    This supprised me (less so when I took in the intentional simularity between normal and virtual methods) and I'm looking for infomation about it.

    Regards
    Last edited by couling; January 20th, 2009 at 07:00 AM. Reason: code correction
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  6. #6
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,116

    Re: Why is ((foo*)NULL)->bar(); undefined?

    While most compilers use a machine language "Jump to Subroutine" instruction for non-virtuals, and a _vptr/_vtable for virtuals, this is by no means mandated by the standard.

    Also consider what happens as soon as you overload "operator ->" .....
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  7. #7
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Why is ((foo*)NULL)->bar(); undefined?

    This bit, isn't undefined:
    Code:
    class foo {
        int bar() {
            if (this == 0) return 0;
            else return 1;
        }
    }
    since in principle it is just comparing a NULL pointer to 0, which is fine. But because that pointer is the this pointer, the process of getting to the code when this is NULL is undefined. i.e.

    Code:
    int main(int argC, char ** argV) {
        std::cout << ((foo *) 0)->bar();
        return 0;
    }
    Constitutes undefined behaviour, because operator-> is dereferencing a NULL pointer, which is undefined behaviour.

    The fact that it works on most compilers because of the way they construct machine code for non-virtual member functions, and consequently the way they access them is irrelevant. The fact is, that the behaviour according the the standard is undefined, and therefore code such as the above should never be implemented.

  8. #8
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: Why is ((foo*)NULL)->bar(); undefined?

    TheCPUWizard Thanks, that pretty much explains it.
    In different implamentations there may be a completely different meaning to that code.

    I've just found this in the 2003 standard which pretty much nails it down.
    ISO/IEC 14882 Second edition 2003-10-15
    9.3.1 Nonstatic member functions
    ...
    If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived
    from X, the behavior is undefined.
    In this case bar is being called on something which is not an object of type foo.

    Thanks for all your responses
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  9. #9
    Join Date
    Nov 2008
    Location
    Netherlands
    Posts
    77

    Re: Why is ((foo*)NULL)->bar(); undefined?

    its undefined because the NT header is not a foo object

  10. #10
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: Why is ((foo*)NULL)->bar(); undefined?

    Sorry I'm not familiour with the term NT header in this context.
    And I'm not getting any meaningful hits on google or in the c++ standard.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  11. #11
    Join Date
    Nov 2008
    Location
    Netherlands
    Posts
    77

    Re: Why is ((foo*)NULL)->bar(); undefined?

    sorry, the correct term is PE Header
    the fact on XP dos header direct to nt header.

    its only on windows, nott C++ standard

  12. #12
    Join Date
    Nov 2003
    Posts
    1,405

    Re: Why is ((foo*)NULL)->bar(); undefined?

    Quote Originally Posted by couling View Post
    It's clear that most compilers will allow this and most of them will simply print 0 and terminate with exit code 0. But the implication in other threads is that the result is undifined.
    It follows from the meaning of undefined behaviour. A compiler can do anything including nothing.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)