Как определить переопределенные макросы в C? - PullRequest
1 голос
/ 22 июня 2010

У меня есть две большие библиотеки фреймворков, чьи заголовочные файлы включены в мой проект. Любой из них работает безупречно, но включение обоих приводит к ошибочному поведению (но нет сообщений об ошибках, связанных с макросом).

Я предполагаю, что они оба # определяют макрос с одинаковым именем. Как наиболее эффективно определить проблемный макрос?

Ответы [ 6 ]

5 голосов
/ 22 июня 2010

Я предполагаю, что они оба # определяют макрос с одинаковым именем.

Это должно генерировать хотя бы предупреждение компилятором (если они находятся в одной и той же единице перевода).

Как определить переопределенные макросы в C / C ++?

Насколько я знаю, прямого пути нет.

Любой из них работает безупречно, но в том числе и то и другое приводит к ошибочному поведению

Не могли бы вы дать нам некоторые подробности об этом поведении? Что на самом деле происходит? Что заставляет вас думать, что это макроопределения?

3 голосов
/ 22 июня 2010

Попробуйте посмотреть на предварительно обработанный вывод, чтобы определить, что в нем отличается, когда вы #include используете файлы заголовков, а когда нет. С gcc и с MSVC вы должны скомпилировать с -E, чтобы вывести выходные данные препроцессора на стандартный вывод. (Вероятно, это будет много тысяч строк, поэтому вы захотите передать его в файл.)

3 голосов
/ 22 июня 2010

Если заголовочные файлы плохо написаны и #undef SYMBOL ... #define SYMBOL something-else, вы не можете отследить это. Простое # определение макроса дважды должно как минимум выдать предупреждение. Вы должны были бы более внимательно посмотреть на «непредсказуемое поведение».

2 голосов
/ 06 августа 2010

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

Вы можете контролировать типы символов, которые ctags будет хранить в вашем файле тегов, используя опцию --c-kinds. например. ctags --c-kinds=+d -f tags --recurse ./your_source_directory/

Затем можно выполнить поиск дубликатов в файле результирующих тегов.

1 голос
/ 22 июня 2010
  1. Компилировать все предупреждения - они должны сообщать вам, когда макрос «уже определен» (возможно, вы можете изменить код, чтобы исправить это)
  2. Если (1) не помогает, тогда вы должны попытаться создать оболочки функций для каждой библиотеки. Таким образом, вы избегаете включения конфликтующих заголовков, включая упакованные заголовки, используя упакованные функции. Это трудоемко, но иногда это единственный способ заставить две библиотеки сосуществовать в приложении.

В основном решение (2) будет разделять библиотеки. Примером такого конфликта является ACE с wxWidgets (версия 2.8) при принудительном использовании предварительно скомпилированных библиотек, скомпилированных с различными параметрами (одна библиотека Unicode, другая ASCII).

1 голос
/ 22 июня 2010

grep для #define?

Вы уверены, что проблема не в чем-то другом, кроме макроса (например, прагмы для упаковки структуры, глобальные распределители памяти, глобальное пространство имен для имен классов, работа с локалью ...)

...