Не найдена несоответствующая лексема visual studio
Я установил Visual Studio 2015 и обнаружил, что в некотором моем коде (с которым не было проблем в VS 2013 ) теперь есть ошибки, обозначенные зелеными волнистыми линиями (которые предполагаются быть новой функцией повышения производительности ). Тем не менее, код по-прежнему успешно компилируется.
Вот небольшой пример:
Вот эти загогулины
Наведение на них мыши говорит мне, что
Определение функции для test1 не найдено
Определение функции для test2 не найдено
Каким-то образом получается, что только функции, объявленные внутри безымянного пространства имен, вызывают волнистые линии.
2 ответа
Зеленые волнистые линии не говорят вам об ошибке, они говорят вам, что есть возможность для новых инструментов рефакторинга что-то сделать. (Красные волнистые линии указывают на ошибку.) В этом случае они информируют вас о том, что не существует определения, соответствующего объявлению test2 , поэтому IDE предлагает его сгенерировать.
Это указывает на ошибку, которая всегда присутствовала в коде, хотя Visual Studio может вести себя несоответствующим образом.
Так что же происходит? Проблема в том, что объявления в безымянном пространстве имен не объявляют те же функции, которые вы позже определите в глобальном пространстве имен. Инструменты рефакторинга распознают это и предлагают сгенерировать определение объявленных функций.
Однако все это все равно компилируется из-за того, что компилятор Microsoft принимает два строго незаконных фрагмента кода. Во-первых, использование префикса пространства имен в первом объявлении функции не допускается. Затем код в main предположительно вызывает функции. Как показал Алекс М в своем ответе, GCC тоже не примет это, поскольку вызов неоднозначен. Компилятор Microsoft, похоже, принимает это, либо рассматривая определение как определение, соответствующее объявлению в безымянном пространстве имен (помните, инструменты IDE, IntelliSense и рефакторинга использовали более совместимый интерфейс EDG, а не синтаксический анализатор, компилятор использует, что означает, что рефактор может сказать, что объявление не имеет определения, в то время как компилятор рассматривает определение как соответствующее объявлению) или просто предпочитает глобальную версию версии с пространством имен.
Между прочим, два случая легко отличить. Измените код так, чтобы main находился перед определениями функций. Это разрешит двусмысленность в GCC, потому что объявлена только функция пространства имен (а не определена, поэтому вы должны получить ошибку компоновщика). Это также приведет к ошибке компоновщика в компиляторе Microsoft, если он просто предпочитает глобальную версию, но все равно будет компилироваться, если он будет рассматривать объявление и определение как соответствие.
Решение всего этого очень простое: при определении функций, объявленных в безымянном пространстве имен, просто повторно откройте пространство имен вместо того, чтобы пытаться определять функции снаружи.
Это компилируется нормально, с указанной вами лампочкой:
Но IntelliSense также выводит (в обоих случаях):
Но действительно ли это то, что вы хотите сделать? Как указано в n4527 в § 7.3.1.1:
определение-безымянного-пространства-имен ведет себя так, как если бы оно было заменено на
где встроенный появляется тогда и только тогда, когда он появляется в определение-пространства-имен-имен и все вхождения unique в единице перевода заменяются одним и тем же идентификатором, и это идентификатор отличается от всех других идентификаторов в единице перевода.
Это проясняет, почему возникают неясности. Просто определите свои методы внутри вашего безымянного пространства имен, поскольку они отличаются от всего остального за его пределами.
Для записи, GCC 5.2.0 и clang 3.6.0 не согласятся скомпилировать код, скомпилированный MSVC.
Читайте также: