Meditation, The Art of Exploitation

Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.

Wednesday, April 26, 2006

Declaration or Definition?

Originally by Jerry Coffin from clcm (editted formatting)

> Given a class Foo:
> class Foo
> {
> Foo() { ... }
> ~Foo() { ... }
> };

As it stands at the moment, you've made Foo::Foo (and ~Foo) private, so you can't create any objects of type Foo. Presumably that was just a slip that entered during posting though. Something like this might be more informative:

struct Foo {
Foo() { std::cout << " ctor"; } ~Foo() { std::cout << " dtor"; }

};

This allows the rest of the code to compile and gives a bit of information about when the ctor and dtor are invoked.

> What's the difference between the following four functions?

> void bar() { Foo; }

This is ill-formed. "Each declarator contains exactly one declrator-id; it names the identifier that is declared." I believe a conforming compiler is required to issue a "diagnostic" for this code (though it can choose to compile it anyway, and if so treat it more or less as it chooses). It looks like MS fails to issue a diagnostic, but interprets this in an obvious way -- as not really declaring anything, so it's basically a nop.

> void bar() { Foo(); }

I'm not _entirely_ certain but I think this is allowed, and should create a temporary object of type Foo() with default initialization.

> void bar() { Foo myFoo; }

This is definitely allowed. It defines an object named myFoo of type Foo that's default initialized.

> void bar() { Foo myFoo(); }

This is definitely allowed as well. Unfortunately, this is one that has probably thrown every C++ programmer on earth at least once (it certainly has me anyway). As the warning message you got implied, this is a function declaration. It declares a function named myFoo that takes no parameters and returns an object of type Foo.

Sections 6.8 and 8.2 of the standard give a number of similar examples -- some of which require careful reading to figure out why they're interpreted the way they are. For a couple of examples from section 8.2:

void foo(double a)
{
S x(int()); // function declaration
S y((int)a); // object declaration

}

Simplifying (quite) a bit, a pattern like this gives a function declaration:

type name(type);

where a pattern like this gives an object declaration:

type name(value);

If the parentheses are empty, the compiler treats it as an empty type specification instead of an empty value, so you end up declaring a function instead of an object.

SFINAE

Substitution Failure Is Not An Error

From Wikipedia, the free encyclopedia (editted formatting)

Substitution Failure Is Not An Error (often referred to by the acronym SFINAE) is a compilation principle in object oriented programming, applied to C++ template programming in particular.

In attempting to use function template argument deduction to select among a number of candidate function templates, a C++ compiler may attempt an instantiation that fails on one or more of them.

For example, consider the following C++ program:

  template  void f( T );
template void f( T * );
//…
f( 1024 ); // instantiates first f

Even though substitution of the integer for T * in the second f function template would have been incorrect, the attempted substitution does not give rise to an error provided that a correct substitution is found. In this case, the first f is instantiated, and there is no error. Thus, we have the “substitution failure is not an error” concept, dubbed SFINAE by David Vandevoorde and Nicolai Josuttis. SFINAE is an important property in that, without it, it would be difficult to overload function templates; the combination of argument deduction and overloading would render many uses of a set of overloaded function templates illegal. But SFINAE is also valuable as a metaprogramming technique.

Monday, April 24, 2006

C++ Forcing a certain storage for your objects and 'delete this'

Forcing a certain storage for your objects

Originally posted at http://www.ciprian-miclaus.com/tips/enforce.asp?tip=b&id=3 (editted formatting)

In general we don't care if our classes get instantiated on the stack or on the free store (the storage where new/delete allocate memory vs. heap which is used to denote the storage used malloc/free). But there are cases when we would like our classes to be instantiated only on the stack or only on the free store. Why would we want something like this? Let's say we end up with a pointer to an object which we own. Should we or should we not delete it? If the object is on the free store and we do not delete it, we end up with memory leaks. However, if the object is on the stack and we're trying to delete it, we'll obviously end up with a splendid crash.

As a rule of thumb, whoever creates an object should destroy it too, so the whole thing about where it was created is generally not a problem. However, there are cases when parameters are passed asynchronously and they're usually created on one side and destroying something else, maybe in different threads. Then usually we'll want to allocate parameters on the free store. But we'll also want to enforce that they should be allocated only on the free store as one might allocate them on the stack and the parameters might be destroyed by the creating-end before they're examimded by the other end.

So, such enforcements of the storage used by certain classes are not totally futile. Let's see how can we enforce in C++ that a class should be instantiated only on the stack or only on the free store. This is about how and where objects are created. So we're probably want to take a look at areas like constructors, destructors, operator new, operator delete, copy constructor, because those are the places where an object of a certain type gets constructed. We also have the access specifiers: public, protected, private. By playing with these toys, we should achieve our purpose.

Forbidding a class to be instantiated on the free store is simple. Just make the operator new and delete protected or private, and client code will not be able to call them, so they will be enforced to instantiate it on the stack.


class OnlyOnStack {
public:
//constructor
OnlyOnStack ();
//destructor
~OnlyOnStack ();

//..public interface here

private:
operator new (size_t) {}
operator delete (void*) {}

};
The choice between protected and private it's the choice between letting your subclasses instantiate on the free store or not. Usually you'll make them private, as subclasses should abide the rules too, but depends on the implementation. If you don't know which is good for you, then choose private.

Forbidding a class to be instantiated on the stack seems simple too. If we simple make the constructors protected or private, we will not be able to instantiate it on the stack. Simple enough. Not quite. When a class gets instantiated on the free store, two things happens:


1. operator new is called (if the class doesn't have an operator new,
then the global operator new is used) that allocates memory for the object
2. the constructor is called
Obviously if the constructor is protected or private, this 2 steps process will fail, and the compiler will signal such a failure fortunately at the compile time. operator new must be public, so what else we got? Destructor. What option? Make it protected or private. Ok, let's see what happens:

class OnlyOnFreeStore {
public:
//constructor
OnlyOnStack ();

//..public interface here

private:
//destructor
~OnlyOnStack ();

};
If we try to instantiate it on the stack with a simple:

OnlyOnFreeStore trivialInstance;
the compiler will complain because when the variable trivialInstance goes out of scope and it should call the destructor, it discovers it cannot as you made the destructor protected or private. Well done! You enforce it not to be on the stack. How about the free store? We'll notice that

OnlyOnFreeStore* pOnlyOnFreeStore = new OnlyOnFreeStore;
it's perfectly legal and the compiler doesn't complain about it. Indeed, it doesn't have any reasons to complain: the constructor is public, and it'll use the global operator new as we haven't defined a custom operator new for this class. How about:

delete pOnlyOnFreeStore;
Well, what happens is:
1. Compiler calls the destructor to destruct the object
2. Compiler calls operator delete the memory allocated for the object
Pretty fair. We've constructed it in 2 steps, we're destroying it in 2 steps. But the destructor is protected or private, so it cannot call it. Here the compiler will complain at compile time (fortunatelly). We cannot give up destructor made protected or private, it's our last hope. Instead let's add to the public interface a method for object destruction.

class OnlyOnFreeStore {
public:
//constructor
OnlyOnStack ();

DeleteThis () {
delete this;
}
//..public interface here

private:
//destructor
~OnlyOnStack ();

};
DeleteThis simply calls delete this, as it can access the private destructor, so everything will work fine. Calling delete this from a member method is however dangerous for at least two reasons:

1. From inside the method we cannot tell if this it's on the stack or on the free store which brings us to the beginning of this tip (we've assure our object is on the free store all the time)

2. After calling DeleteThis the object is destroyed and you cannot use it (it's equivalent to delete pOnlyOnFreeStore) just that users are not familiar with this technique as opposed to the classical delete pointer, so the technique it's error-prone.

However, this is our solution. So we'll use our class like this:

OnlyOnFreeStore* pOnlyOnFreeStore = new OnlyOnFreeStore;
//...use the object here
pOnlyOnFreeStore->DeleteThis ();
//the object is destroyed
Mission accomplished...