Destructor
Destructor

Reputation: 14438

why MSVS allows NULL as pure virtual function specifier?

Consider following program:

struct Test
{
    virtual void foo()=NULL;
};
int main()
{ }

g++ 4.8.1 gives an expected error as following:

[Error] invalid pure specifier (only '= 0' is allowed) before ';' token

Clang gives following error:

error: initializer on function does not look like a pure-specifier

But when I tried it on MSVS 2010 it compiles & runs fine. I think g++ & clang is right in this case. What the standard says about this? I've disabled compiler extensions also using \Za command line option but MSVS still accepts that code. Why it isn't giving any error?

I also tried it on Online VC++ Compiler here that has been last updated on July 8, 2015. Is this really bug in MSVS 2010 & 2015?

Upvotes: 4

Views: 459

Answers (3)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158479

The grammar in section 9.2 Class members says the following:

[...]
member-declarator:
 declarator virt-specifier-seqopt pure-specifieropt
[...]
pure-specifier:
  = 0
  ^^^

So the pure-specifier has to be a literal 0. Most likely NULL is defined as 0 for MSVC but it does not have to be defined as 0, another possibility is 0L which is not allowed by the grammar and this is possibly what gcc and clang use.

We can see this from section 18.2:

The macro NULL is an implementation-defined C++ null pointer constant in this International Standard 194

the footnote says:

Possible definitions include 0 and 0L, but not (void*)0.

and section 4.10 says:

A null pointer constant is an integer literal (2.14.2) with value zero

which rules out (void*)0.

Earlier versions of clang and MSVC accepted other integer literals but it looks like clang fixed this in the latest revision.

Upvotes: 1

TartanLlama
TartanLlama

Reputation: 65620

NULL is specified to be an implementation-defined C++ null pointer constant, which is an integral constant expression evaluating to zero or a prvalue of type std::nullptr_t. As such, 0, 0L or nullptr are all valid implementations of NULL.

Your versions of Clang and GCC probably define it as 0L or nullptr, whereas your MSVC version defines it as 0. In that case, the preprocessor will replace NULL with 0, making your program well-formed.

Upvotes: 2

Bartek Banachewicz
Bartek Banachewicz

Reputation: 39380

According to MSDN, NULL is defined as something that is close enough to 0 for MSVC++ to swallow. That's it.

Try doing #undef NULL before that code, and it should properly break compilation.

Upvotes: 2

Related Questions