Re: Why is nullptr unsafe?
DeMarcus wrote:
Hi,
I implemented the nullptr workaround found here in Section 1.1.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
However, I get some nasty behavior when initializing static variables.
Here is the code.
// From N2431, Section 1.1.
const
class
{
public:
template<class T>
operator T*() const { return 0; }
template<class C, class T>
operator T C::*() const { return 0; }
private:
void operator&() const;
} nullptr = {};
// My test (in the same file).
#include <iostream>
#include <assert.h>
template<typename T>
class StaticInit
{
public:
static T& value()
{
std::cerr << "value() - "
<< "Initialied: " << initialized_
<< " Pointer: " << pointer_ << std::endl;
if( initialized_ == false )
{
pointer_ = new T;
initialized_ = true;
}
assert( pointer_ );
return *pointer_;
}
private:
static T* pointer_;
static bool initialized_;
};
template<typename T>
T* StaticInit<T>::pointer_ = nullptr;
template<typename T>
bool StaticInit<T>::initialized_ = false;
typedef StaticInit<int> SIInt;
struct SomeClass
{
SomeClass() { SIInt::value() = 47; }
} someClass; // NOTE! Static variable calling SIInit.
struct SomeClass2
{
SomeClass2() { SIInt::value() = 11; }
} someClass2; // NOTE! Static variable calling SIInit.
int main()
{
std::cerr << SIInt::value() << std::endl;
}
When I run this program I get two initializations of pointer_. First I
get the mandatory zero-initialization [?3.6.2/2]. Then I get pointer_
initialized when SIInt::value() is called from SomeClass. After that I
get pointer_ initialized again with nullptr!
I think I found the answer myself. For those interested in this issue I
found the N2235 Generalized Constant Expression document.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
Read Section 3.4 Unexpected dynamic initialization.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]