Не найдена несоответствующая лексема visual studio

Обновлено: 05.07.2024

Я установил Visual Studio 2015 и обнаружил, что в некотором моем коде (с которым не было проблем в VS 2013 ) теперь есть ошибки, обозначенные зелеными волнистыми линиями (которые предполагаются быть новой функцией повышения производительности ). Тем не менее, код по-прежнему успешно компилируется.

Вот небольшой пример:

Вот эти загогулины

enter image description here

Наведение на них мыши говорит мне, что

Определение функции для 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.

Читайте также: