Ich habe ein Problem mit Visual Studio 2012. Zuerst die SSCCE:
class CacheImpl
{
public:
float* m_cache;
CacheImpl()
{
m_cache=(float*)new float[1];
}
~CacheImpl()
{
delete [] m_cache;
}
};
class Image
{
public:
Image() {}
~Image() {}
};
static const Image g_tmpImg;
class Filter
{
public:
Filter() : m_img(Image())
//Filter() : m_img(g_tmpImg) // <-- This variant works
{
//Empty
}
private:
CacheImpl m_cache;
const Image &m_img;
};
int main()
{
Filter f;
return 0;
}
Wenn ich dies ausführe (kompiliert im Debug-Modus), erhalte ich eine CRT-Assert auf das Löschen in CacheImpl, und ein Blick auf das Assembly-Listing von Filter() oder das Setzen eines Haltepunkts in ~CacheImpl() zeigt, dass ~CacheImpl() am Ende des Filter-Konstruktors ohne ersichtlichen Grund aufgerufen wird (und in der Tat geschieht dies nicht in VS2010). Stattdessen wird ~Image() für das temporäre Objekt aufgerufen, das VS2012 nicht tun.
Beim Kompilieren dieses in VS2012 erhalte ich die Warnung "C4413: 'Filter::m_img' : reference member is initialized to a temporary that doesn't persist after the constructor exits". Das verstehe ich, aber ich erwarte eine baumelnde Referenz und keinen Absturz, weil das falsche Objekt zerstört wird. Bin ich über einen Compiler-Bug gestolpert oder sollte ich dies einfach als undefiniertes Verhalten akzeptieren und keine Referenzen auf temporäre Objekte initialisieren? Für den Kontext, in meinem realen Code die baumelnden Verweis wird nie verwendet, wenn Filter mit einem solchen Konstruktor erstellt wird.