1

When I am compiling the following program with clang++ version 5.0, it is resulting in

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

extern void print(void *ptr);

#define NULL __null

class IInterface
{
public:
    virtual void method1() = NULL;
};


int main()
{
    void *ptr = NULL;
    print(ptr);
    return 0;
}

It seems __null is not supported by clang? But some posts in stackoverflow suggests clang supports __null. If so why am I getting this error. Could somebody suggest whats going on here?

Link: https://godbolt.org/z/-f3Kf9

Pendyala
  • 585
  • 1
  • 6
  • 17

3 Answers3

10

The syntax for pure virtual function is only = 0. For example, virtual void do_stuff() = 0 is allowed, but virtual void do_stuff() = nullptr is not allowed.

Clang does support __null but that compiler internal is not meant to declare virtual functions.

The only reason that NULL might work for pure virtual functions is that some system define it as 0, but you should not rely on that. Some compiler might also use 0LL or (void*)0.

If you can, you should use nullptr instead of NULL for declaring null pointers. This is the best solution and can be emulated in older standards.

For declaring pure virtual functions, use = 0. This is the simplest and the usual way to declare pure virtual functions.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • Might need a little rewording; right now the first paragraph appears to contradict with the last paragraph, until you look closer – Lightness Races in Orbit Nov 06 '19 at 18:26
  • @Lightness... Thank you... So __null is keyword? Its not macro? where can I see its definition? – Pendyala Nov 06 '19 at 18:33
  • 1
    It's not really a keyword, but a compiler internal. You can usually recognise those with the leading double undescore. – Guillaume Racicot Nov 06 '19 at 18:40
  • @Pendyala Apparently [it's an implementation detail](https://stackoverflow.com/a/8783589/560648) (that answer is about GCC but Clang has some similar things), so... neither really. It certainly isn't standard. I have no idea why you chose to use it. – Lightness Races in Orbit Nov 06 '19 at 18:40
  • 2
    [By the Holy Laws of C++](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier), anything that contains two underscores in a row is an implementation detail that is not portable and may vanish any time you upgrade your tools. That or it's a potential programming mistake that can result in very confusing errors or runtime behaviour. – user4581301 Nov 06 '19 at 18:45
3

This seems to be some sort of misunderstanding here. Making a virtual function pure is not the same thing as initializing it to a null pointer. In fact, some compilers will set the vtable entry for a pure function to point to a special function called __cxa_pure_virtual or something like that.

Since you are not actually initializing a pointer, you can't use __null here. Not even GCC 4.1 allows it. Nor can you use nullptr, which is the standard replacement for __null. Just write = 0; here.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
2

What is going on here is:

  1. For some reason, you're using a compiler internal (__null) instead of the standard nullptr (at worst, the old NULL was already in the standard and did not need defining by you)

  2. For some reason, you're trying to use __null (or NULL (or nullptr)) as a pure virtual function specifier. You can't do that. It's supposed to be = 0. I believe GCC permits, or used to permit, what you're doing as an extension; Clang doesn't.

Simple as that really!

Your next steps:

  1. Stop using __null for null pointers; use nullptr instead.
  2. Stop using null pointers for pure virtual function specifiers. It's = 0.
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055