Thread: Undefined behavior from VC6 to 2k5

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838

    Undefined behavior from VC6 to 2k5

    i've inherited some (atrocious) code that was written in VC6 and when executing it in 2k5, the results are totally different.

    so far, i've already identified one instance of relying on undefined behavior - where apparently 2k5 is more aggressive in taking variables off the stack than VC6. e.g:

    Code:
    class foo
    {
        public:
            std::string mystring()
            {
                return _mystring;
            }
        private:
            std::string _mystring;        
    };
    
    void func()
    {
        foo f;
        const char* const invalidPtr = f.mystring().c_str();  //this was ok in VC6, but 2k5 now properly deletes the copy of _mystring being retuned
    }
    if anyone else has any experience they could impart to me, gotchas such as the above, i'd appreciate it. i have probably well over a hundred thousand lines to comb through, and i'm armed only with the knowledge that 'it used to work'.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Gimpel Software PC-lint Overview
    There's even an online demo where you can try things.

    If someone is paying you for your time, then the $400 price is a bargain.

    If you've got 100K lines of code that have never been linted, it will have a field day!
    Pick any one that would have taken you a day to find through compile, test, crash and you're in the money.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    hahaha i know it's been linted - he's got comments in there specifically suppressing lint output

    evidently it didn't catch the one above, or he ignored it.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > he's got comments in there specifically suppressing lint output
    Tell me about it!
    I've seen all sorts of horrors where people have thought it better to shoot the messenger than address the problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Out of curiosity, what's wrong with this:

    Quote Originally Posted by m37h0d View Post
    Code:
    class foo
    {
        public:
            std::string mystring()
            {
                return _mystring;
            }
        private:
            std::string _mystring;        
    };
    
    void func()
    {
        foo f;
        const char* const invalidPtr = f.mystring().c_str();  //this was ok in VC6, but 2k5 now properly deletes the copy of _mystring being retuned
    }
    Why should the compiler delete "the copy of _mystring being returned"?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    he returns by value, thus the pointer that he gets from std::string::c_str() becomes invalid as the destructor is called on the temporary rvalue object.

  7. #7
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    mystring returns a copy of the string. The std::string copy is a temporary and lives until c_str() returns, then its destructor is called. The pointer returned by c_str is valid until the string it came from is modified, destruction is a modification. The pointer points to something that has been deallocated, it is invalid.

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    FTFY:
    Code:
        const std::string& validStr = f.mystring();
    Const references extend the lifetime of temporaries, so yes this is valid!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    fwiw, the fix i chose was

    Code:
            const std::string& foo::mystring()
            {
                return _mystring;
            }
    this fixes the problem everywhere, but doesn't require any changes to the dependent implementations.

  10. #10
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i've found something else a bit mind boggling - in the watch window float have an additional 2 digits of precision on 2k5. i don't know if this is a presentation issue (i.e. the watch window is rounding off at so many digits of precision), or if there is a genuine difference in the floating point precision between vc6 & 2005. i found something on msdn that said 2005 has a new engine for handling floating point precision, but the tables that have the data type specifications say they are identical between the two versions.

    very odd.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    VC6 and 2005 both employ IEEE floating point formats, so would not change between versions. There are almost as many views on presentation of floating point (eg in debuggers) as there are people who care about it, so it is no surprise that the presentation changes between versions.

    VC6 was released at about the same time the C++ standard was ratified, and is rather famous for lack of compliance with the standard. There were numerous deficiencies related to handling of templates (although a lot of them will tend to be picked up by warnings or errors in later compilers, if you ratchet up the warning levels from defaults) and a number of Microsoft-specific extensions. One thing to watch is that VC6 tended to keep temporaries alive significantly longer than was ever required in the standard - which actually meant VC6 was somewhat forgiving of sloppy programming.

    It's one reason VC6 was quite popular with some people, while hated by others.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Unexplainable behavior...
    By wpcarro in forum C Programming
    Replies: 6
    Last Post: 01-06-2011, 06:15 PM
  2. openGL: textures, gluLookAt, and undefined behavior
    By MK27 in forum Game Programming
    Replies: 7
    Last Post: 04-28-2009, 10:12 AM
  3. OT:Sorry for my rude behavior
    By moussa in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 06-03-2008, 06:20 AM
  4. Scanf behavior
    By devilhaunts in forum C Programming
    Replies: 3
    Last Post: 08-06-2006, 06:21 PM
  5. Weird cin behavior
    By Link_26 in forum C++ Programming
    Replies: 4
    Last Post: 06-25-2006, 09:25 PM