visual studio — Можно ли безопасно игнорировать предупреждения LNK4006 в смешанных решениях на Fortran / C ++?

Наше текущее решение — это смешанное приложение C ++ Fortran в Visual Studio 2013, в котором примерно 40 проектов.

Несмотря на то, что мы можем хорошо построить решение, мы получаем около 6000 предупреждений — подавляющее большинство из которых — предупреждения LNK4006, где функция «дублируется»:

warning LNK4006: _XXXXXXXXXXX@8 already defined in project1.lib(module1.obj); second definition ignored project2.lib(module1.obj)

Общий поток состоит в том, что дублируемые функции определены в модулях Fortran, многие из которых являются просто интерфейсами для функций C ++:

MODULE mINTERFACES

USE ISO_C_BINDING

INTERFACE
INTEGER(4) FUNCTION GetLastErrorCode [C, ALIAS: '_GetLastErrorCode'] (index)

USE ISO_C_BINDING

INTEGER(C_SIZE_T), INTENT(IN) :: index
END FUNCTION GetLastErrorCode
END INTERFACE

END

Поскольку эти модули используются во многих проектах на Фортране, каждый проект имеет независимую версию функции интерфейса — отсюда дублирование.

Все это имеет смысл, но мой вопрос таков: могу ли я просто игнорировать предупреждения (т.е. исключать их из конфигурации проекта)? Я не вижу никакого очевидного способа реструктуризации нашего кода для удаления предупреждений, и у меня сложилось впечатление, что размещение этих интерфейсов в модуле было хорошей практикой …

1

Решение

Спасибо всем, кто конструктивно прокомментировал эту ветку, а также @IanH и Стиву Лайонелу, которые помогли в ветке форума Intel на https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/628995.

Короче

(И это мое собственное, а не чужое мнение) В данном конкретном случае предупреждения мы лишнее, НО, если вы отключите их, вы пропустите любые новые предупреждения, которые могут быть важны. ИМХО это означает, что вы не должны отключать предупреждение.

Длинный ответ

Предупреждения исходили из двух источников:

  1. Возросло соглашение о том, чтобы использовать модуль для хранения «глобальных» данных, но для доступа к ним через «функции доступа», которые были определены в тех же файлах, что и модули. Это означало, что когда модули были включены во многие различные проекты, функции доступа были скомпилированы несколько раз.
  2. Некоторые из этих модулей содержали блоки интерфейса C (что является хорошей практикой), но для функций, которые возвращали строки, использовалась парадигма, как описано в Создание интерфейса FORTRAN для функции C, которая возвращает символ *. Хотя сами блоки интерфейса не выдавали предупреждение о дублировании, вторичные функции, которые преобразовывали указатель C в строку Fortran, сделали это.

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

Благодаря @IanH он отметил, что вы можете избежать этого, определив все модули в отдельном проекте, а затем (в Visual Studio) просто настроить все проекты так, чтобы они зависели от этого нового проекта «общих модулей» (используя Зависимости сборки -> Зависимости проекта). Это теперь компилируется без предупреждений; Поиск VS «полного решения» теперь находит каждую подпрограмму только один раз; и это, вероятно, компилируется намного быстрее! В общем, победа.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru