Clang поддерживает __null? - PullRequest
       30

Clang поддерживает __null?

1 голос
/ 06 ноября 2019

Когда я компилирую следующую программу с помощью clang ++ версии 5.0, это приводит к ошибке

: инициализатор функции не похож на чисто спецификатор

extern void print(void *ptr);

#define NULL __null

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


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

Кажется, __null не поддерживается clang? Но некоторые сообщения в stackoverflow предлагают, чтобы clang поддерживал __null. Если так, то почему я получаю эту ошибку. Кто-нибудь может подсказать, что здесь происходит?

Ссылка: https://godbolt.org/z/-f3Kf9

Ответы [ 3 ]

10 голосов
/ 06 ноября 2019

Синтаксис для чисто виртуальной функции - только = 0. Например, virtual void do_stuff() = 0 разрешено, но virtual void do_stuff() = nullptr не разрешено.

Clang поддерживает __null, но внутренний код компилятора не предназначен для объявления виртуальных функций.

Единственная причинато, что NULL может работать для чисто виртуальных функций, заключается в том, что некоторая система определяет его как 0, но вы не должны на это полагаться. Некоторые компиляторы могут также использовать 0LL или (void*)0.

Если вы можете, вы должны использовать nullptr вместо NULL для объявления нулевых указателей. Это лучшее решение, которое можно эмулировать в более старых стандартах.

Для объявления чисто виртуальных функций используйте = 0. Это самый простой и обычный способ объявления чисто виртуальных функций.

3 голосов
/ 06 ноября 2019

Кажется, здесь есть какое-то недоразумение. Сделать виртуальную функцию чистой - это не то же самое, что инициализировать ее нулевым указателем. Фактически, некоторые компиляторы устанавливают запись vtable для чистой функции, чтобы она указывала на специальную функцию с именем __cxa_pure_virtual или что-то в этом роде.

Поскольку вы фактически не инициализируете указатель, вы не можете использовать __null здесь. Даже GCC 4.1 не позволяет это. Также вы не можете использовать nullptr, который является стандартной заменой __null. Просто напишите = 0; здесь.

2 голосов
/ 06 ноября 2019

Что здесь происходит:

  1. По какой-то причине вы используете внутренний компилятор (__null) вместо стандартного nullptr (в худшем случае,старый NULL уже был в стандарте и не требует определения вами)

  2. По какой-то причине вы пытаетесь использовать __null (или NULL (или nullptr)) как чисто спецификатор виртуальной функции . Вы не можете сделать это. Это должно быть = 0. Я полагаю, что GCC разрешает или используется для разрешения того, что вы делаете как расширение;Clang не делает.

Очень просто!

Ваши следующие шаги:

  1. Прекратить использование __null для нулевых указателей;вместо этого используйте nullptr.
  2. Прекратите использовать нулевые указатели для чисто спецификаторов виртуальных функций. Это = 0.
...