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

Рассмотрим следующую программу:

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

g ++ 4.8.1 выдает ожидаемую ошибку следующим образом:

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

Clang выдает следующую ошибку:

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

Но когда я попробовал его на MSVS 2010, он компилируется и работает нормально. Я думаю, что g ++ & Clang прав в этом случае. Что стандарт говорит об этом? Я отключил расширения компилятора, также используя параметр командной строки \ Za, но MSVS по-прежнему принимает этот код. Почему это не дает никакой ошибки?

Я также попробовал его на онлайн-компиляторе VC ++ здесь , последнее обновление которого было 8 июля 2015 г. это действительно ошибка в MSVS 2010 & 2015?

4 голоса | спросил Destructor 8 +03002015-10-08T18:53:29+03:00312015bEurope/MoscowThu, 08 Oct 2015 18:53:29 +0300 2015, 18:53:29

2 ответа


0

NULL указывается как константа нулевого указателя C ++, определяемая реализацией, которая представляет собой целочисленное константное выражение с нулевым значением или значением типа std::nullptr_t. Таким образом, 0, 0L или ---- +: = 4 =: + ---- - все допустимые реализации nullptr.

Ваши версии Clang и GCC, вероятно, определяют его как NULL или 0L, тогда как ваша версия MSVC определяет его как nullptr. В этом случае препроцессор заменит 0 на NULL, что делает вашу программу правильно оформленной.

ответил TartanLlama 8 +03002015-10-08T19:03:59+03:00312015bEurope/MoscowThu, 08 Oct 2015 19:03:59 +0300 2015, 19:03:59
0

Грамматика в разделе 9.2 Члены класса говорит следующее:

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

Таким образом, чистый спецификатор должен быть литералом 0. Скорее всего, NULL определяется как 0 для MSVC, но его не нужно определять как 0, другая возможность - 0L, что не разрешено грамматикой, и, возможно, это то, что используют gcc и clang.

Это видно из раздела 18.2:

  

Макрос NULL является определенной в реализации константой нулевого указателя C ++ в этом международном стандарте 194

в сноске написано:

  

Возможные определения включают 0 и 0L, но не (void *) 0.

и раздел 4.10 говорит:

  

Константа нулевого указателя - это целочисленный литерал (2.14.2) со значением ноль

который исключает (void*)0.

Более ранние версии clang и MSVC принимали другие целочисленные литералы , но похоже, что clang исправил это в последней редакции.

ответил Shafik Yaghmour 8 +03002015-10-08T19:12:52+03:00312015bEurope/MoscowThu, 08 Oct 2015 19:12:52 +0300 2015, 19:12:52

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132