Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evil samples of subtly broken C++ code

Tags:

c++

I need some samples of bad C++ code that will illustrate violation of good practices. I wanted to come up with my own examples, but I am having a hard time coming up with examples that are not contrived, and where a trap is not immediately obvious (it's harder than it seems).

Examples would be something like:

  1. Not defining copy constructor for classes with std::auto_ptr members, and using std::auto_ptr members with forward-declared classes.
  2. Calling virtual functions from a constructor or a destructor (directly or indirectly).
  3. Overloading a template function.
  4. Circular references with boost::shared_ptr.
  5. Slicing.
  6. Throwing exceptions from C callbacks (directly or indirectly).
  7. Floating point comparison for equality.
  8. Exception safety of constructors with raw pointer members.
  9. Throwing from destructors.
  10. Integer overflow when compiled on different architectures (mismatch of size_t and int).
  11. Invalidating a container iterator.

...or any other evil thing you can think of.

I'd appreciate some pointers to existing resources, or a sample or two.

like image 813
Alex B Avatar asked Nov 28 '10 06:11

Alex B


2 Answers

Code that are not exception safe can fail in ways that are not obvious to the readers of code:

// Order of invocation is undefined in this context according to the C++ standard.
// It's possible to leak a Foo or a Bar depending on the order of evaluation if one
// of the new statements throws an exception before their auto_ptrs can "own" it
accept_two_ptrs(std::auto_ptr<Foo>(new Foo), std::auto_ptr<Bar>(new Bar));

void MyClass::InvokeCallback(CallbackType cb)
{
    Foo* resource = new Foo;
    cb(resource); // If cb throws an exception, resource leaks
    delete resource;
}
like image 155
In silico Avatar answered Oct 17 '22 17:10

In silico


#include <iostream>

class Base
{
    public:
        virtual void foo() const { std::cout << "A's foo!" << std::endl; }
};

class Derived : public Base
{
    public:
        void foo() { std::cout << "B's foo!" << std::endl; }
};

int main()
{
    Base* o1 = new Base();
    Base* o2 = new Derived();
    Derived* o3 = new Derived();

    o1->foo();
    o2->foo();
    o3->foo();
}

And the output is:

A's foo!
A's foo!
B's foo!

Not sure if it has a name, but it sure is evil! :P

like image 16
Palmik Avatar answered Oct 17 '22 19:10

Palmik