недопустимый чистый спецификатор (допускается только `= 0 ') перед'; 'ошибка токена с g ++ - PullRequest
1 голос
/ 21 марта 2011

У меня есть этот код C ++.

#include <string>
#define IC(E) virtual const E const = NULL; 

struct IDumpable
{
    IC(std::string ToDumpString());
};

class Hello : public IDumpable
{
public:
    const std::string ToDumpString() const {
        std::string a("hello"); return a;
    }
};

int main()
{
    Hello hello;
    hello.ToDumpString();
}

Он компилируется / работает нормально с MSVC, но я получил invalid pure specifier (only '= 0' is allowed) before ‘;’ token ошибку с g ++.

Что с ним не так?

Ответы [ 4 ]

3 голосов
/ 21 марта 2011

NULL - это макрос, который g ++, скорее всего, определяет для чего-то другого , чем буквальный ноль, что вполне допустимо. Используйте = 0 явно для объявления абстрактных функций.

Кроме того, я действительно советую не использовать макрос, такой как тот, который вы должны объявлять такими чистыми функциями. Это только сделает вещи менее понятными для будущих сопровождающих, если им придется посмотреть, что это значит, чтобы понять декларацию.

3 голосов
/ 21 марта 2011

GCC использует встроенный __null для NULL (который является константным целочисленным выражением, оцениваемым до нуля. __null в GCC удовлетворяет такому), так что он может обнаруживать особые случаи и предупреждать о них. Например, случайная передача NULL параметру bool, когда он должен был быть передан параметру указателя (изменения, внесенные в функцию, забыли адаптировать сторону вызова).

Как говорится в сообщении об ошибке, для того, чтобы очистить виртуальную функцию, требуется точная последовательность токенов = 0, а не некоторые другие вещи (= 0L или другие тоже не удастся).

2 голосов
/ 21 марта 2011

Что не так, это именно то, что говорится в сообщении об ошибке: только "= 0" разрешено в спецификации чисто виртуальных функций, и вместо этого вы говорите = NULL. Стандарт C ++ определяет NULL как «определяемую реализацией константу нулевого указателя C ++» (C ++ 03 §18.1 / 4). 0 является одной из таких констант нулевого указателя, но NULL не обязательно должно быть 0.

Просто так получилось, что MSVC определяет NULL в 0, но GCC фактически определяет NULL как __null. GCC говорит, что __null является допустимой константой нулевого указателя, но __null не равно 0, поэтому вы не можете использовать ее в спецификации чисто виртуальной функции.

2 голосов
/ 21 марта 2011

Откуда у вас странная привычка использовать макрос NULL в чистом спецификаторе?

Использование NULL в чистом спецификаторе не будет работать. Синтаксис чистого спецификатора: = 0 и только = 0, больше ничего. Если он работал у вас раньше, это просто означает, что компилятор, который вы использовали ранее, определял макрос NULL как обычный 0. Таким образом, по стечению обстоятельств вы можете использовать = NULL как чистый спецификатор при использовании этого компилятора.

Но в общем случае NULL не определяется как простой 0, и, как я уже говорил выше, = NULL не имеет смысла в качестве чистого спецификатора. Она не будет работать. Это именно то, что вы наблюдаете в вашем случае.

...