Пример несоответствующего кода Visual C++?


Каковы некоторые примеры кода, которые не соответствуют стандартам при использовании visual C++? Что-то, что разрешено компилировать под visual C++, но ничего больше.

6 7

6 ответов:

Вы можете найти все расширения языка Microsoft здесь; вы также можете взглянуть на области языка , где VC++ не соответствует стандарту.

Один из них, который я считал стандартным (я заметил это, когда включил переключатель / Za ), - это "магический L-value cast":

char *p;
(( int * ) p )++; 

Некоторые версии Visual C++ допускают передачу неконстантной ссылки на временный объект. Что-то вроде этого:

void DoSomething(std::string& str);

void NonConformantFunction()
{
    DoSomething("Temporary std::string created here");
}

" Что-то, что разрешено компилировать под visual C++, но ничего больше "

И

" код, который не является стандартом соответствие"

Не описывайте в точности одно и то же. Компилятор может быть полностью совместим со стандартом, имея при этом расширения, уникальные для этого компилятора, в то время как несоблюдение является чем-то явно запрещенным стандартом. Существует также ряд "неопределенных" или "определенных реализацией" частей ИСО. стандарт, который может предотвратить переносимость, не будучи несовместимым. Кроме того, многие поддерживаемые расширения поддерживаются другими компиляторами, так что примеры одного из ваших ограничений, но не другого.

Теперь, когда это сказано, основное расширение VC++, которое сделало бы его код непереносимым,-это все расширения C++/CLI, а следовательно, и библиотека классов .NET Framework, которая требует их.

Есть официальная страница на microsoft.com говоря, какие части, где VC++ не совместим со стандартом. Однако другая проблема заключается в том, где он совместим по умолчанию со стандартом. Например, область по умолчанию для переменных for является все еще неправильной в VC++2010.

У меня нет компилятора VC для проверки этого, но если я правильно помню, это будет нормально компилироваться в Visual Studio независимо от комментируемых ошибок:

template <typename T>
struct base {
   void foo() {
      T::type v = 0;    // standard requires typename here
      std::cout << v << std::endl;
   }
};
template <typename T>
struct derived : base<T>
{
   void bar() {
      foo();            // foo() is not dependent this should not compile   
   }
};
struct test {
   typedef int type;
};
int main() {
   derived<test> o;
   o.bar();
}

Одна вещь, которую MSVC++ позволяет вам сделать, - это явно специализировать шаблоны внутри класса. Напр..

class X {
public:
    template <typename T> void doStuff(T value);

    template <> void doStuff<bool>(bool value) {
        // ..do something specific to bool.
    }
};

Это прекрасно компилируется в VS, но попытка компиляции в GCC выдаст ошибку, сообщающую вам, что у вас есть явная специализация в области, не относящейся к пространству имен. Решение этой проблемы состоит в том, чтобы просто растянуть специализацию.

class X {
public:
    template <typename T> void doStuff(T value);
};

template <> void X::doStuff<bool>(bool value) {
    // ..do something specific to bool.
}

GCC прав в этом вопросе, хотя, согласно спецификации, которая утверждает, что все явные специализации должны быть в пространстве имен масштаб.

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