Пример несовместимого кода Visual C ++? - PullRequest
7 голосов
/ 31 января 2011

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

Ответы [ 6 ]

3 голосов
/ 31 января 2011

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

Тот, который я считал стандартным (я заметил это, когда включилПереключатель 1007 * / Za ) - это «магическое приведение значения l»:

char *p;
(( int * ) p )++; 
2 голосов
/ 31 января 2011

"То, что разрешено компилировать под визуальным C ++, но больше ничего "

и

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

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

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

2 голосов
/ 31 января 2011

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

void DoSomething(std::string& str);

void NonConformantFunction()
{
    DoSomething("Temporary std::string created here");
}
1 голос
/ 31 января 2011

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, объявленному для специализации в файле реализации. Однако эта функция не реализована большинством компиляторов, и есть планы удалить ее из следующей версии спецификации.

1 голос
/ 31 января 2011

У меня нет компилятора 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();
}
1 голос
/ 31 января 2011

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

...