marcus obrien Ответов: 2

Как я могу получить список всех директив preprecoesor и их значений ? в частности, #define


Привет,

Работая над огромными проектами, неизбежно возникают миллионы препроцессорных обернутых кодов, s должен видеть

#ifdef MY_COMPLETE_MISLEADING_NAME
//некоторый материал
#endif

Поэтому я хочу видеть, когда я компилирую, какие из этих директив препроцессора определены, а какие нет. Я говорю о VS 2015.Поэтому я хотел бы иметь возможность выбрать конфигурацию сборки, то есть prod/release/debug, а затем просто позволить pre-p разобрать код и вытащить все значения определений и перечислить их, очень быстро, как его предварительная компиляция.

Кто-нибудь знает, как это сделать?



Что я уже пробовал:

Я могу ввести ручной код, чтобы увидеть значения. Поэтому я попытался создать фиктивный файл и сделать это

bool PREP_STUPID_NAME1 = false;
#ifdef STUPID_NAME1
PREP_STUPID_NAME1 = true;
#endif

Хе-хе, Вот в чем дело, есть ли там гениальные гуру препроцессоров, которые могли бы написать макрос, который автоматически генерировал бы файл, о котором я говорю ? Поэтому разберите весь код, вставьте все определения в файл, создайте bool для каждого из них, а затем повторите приведенный выше код и т. д.


Маркус

2 Ответов

Рейтинг:
2

Jochen Arndt

Для компилятора VS нет никакой опции.

Но если вы можете установить GCC/G++ (или уже имеете его), вы можете использовать его вместе с -dM -E опции.

Смотреть также Совет C | C++: как перечислить предопределенные макросы компилятора / программное обеспечение Nadeau[^] для других компиляторов.

[РЕДАКТИРОВАТЬ]
Для обработки всех входных файлов из проекта можно создать Пользовательское Правило Сборки это выполняется для каждого исходного файла. Инструмент может быть самописным парсером или просто GCC/G++ с дополнительной постобработкой (еще один самописный инструмент для фильтрации и форматирования). Кандидатами для инструментов фильтрации являются утилиты командной строки регулярных выражений. Если вы немного знаете Linux, вы можете использовать команда grep и СЭД из Собственные порты Win32 некоторых утилит GNU[^] (UnxUtils).
[/РЕДАКТИРОВАТЬ]


Albert Holguin

+5... но если OP просто пытается найти состояние определения в файле, мое решение, вероятно, является самым простым.

Рейтинг:
1

Albert Holguin

Вы можете делать простые сообщения/предупреждения pragma... вероятно, это проще, чем разбрасывать все содержимое каждого определения препроцессора в большом проекте.

#ifdef SOMEVAR
  #pragma message("SOMEVAR is defined here")
#else
  #pragma message("SOMEVAR is NOT defined here")
#endif

Сообщение Pragma[^]


marcus obrien

Это звучит разумно, было бы здорово иметь script/feature в VS, который бы grep через код выводил все определенные директивы pre-proc в файл с приведенным выше кодом pragma, обернутым вокруг каждой из них, автоматически, а затем можно было бы скомпилировать исходный код и увидеть значения каждого определения в базе кода. Я работаю над VS sln с более чем 300 проектами в нем. Может быть, я мог бы сгенерировать сценарий, если только у кого-то его уже нет ?

Albert Holguin

Не видел ни одного... но я уже давно перешел к набору инструментов gcc.

Stefan_Lang

Я не думаю, что это было бы разумно, или если бы у вас был такой инструмент, то он дал бы вам результаты, которые вы сочли бы разумными. Этот инструмент должен был бы сканировать код, включенные файлы, включенные этим кодом, включенные файлы, включенные включенными файлами, и так далее, вплоть до самого системного заголовочного файла rmeote, который каким-то непонятным образом связан. Поэтому даже самая тривиальная программа в конечном итоге перечислит тысячи символов, определенных в системных заголовках, о которых вы никогда не слышали и которые вас определенно не интересуют.

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

В конце концов, вам все равно понадобится код Альберта, чтобы узнать, действительно ли этот символ известен в том конкретном месте вашего кода, которое вас интересует.

То, что вам нужно, очень сильно зависит от того, что вы хотите сделать с этой информацией.

Если вы хотите убедиться, что новое имя символа, о котором вы думаете, не сталкивается с уже существующим, мой совет состоит в том, чтобы (а) не использовать #define вообще, если вы абсолютно не можете избежать этого, и (Б) просто следовать общим рекомендациям по выбору символов #define.

В остальном решение Альберта Кажется мне прекрасным.

marcus obrien

Привет, столкновение имен-это ни в коем случае не то, что меня интересует. Весь код, над которым я работаю, содержится в пространствах имен, так что это не та проблема, которая меня беспокоит. Я думаю, что вы упустили смысл того, о чем я спрашиваю, то, что я хочу,-это способ сказать, какой препроцессорный код будет включен в текущую конфигурацию сборки.
Результаты будут совершенно разумными, и именно такими, как я хочу. Я действительно хочу знать состояние каждой переменной препроцессора, чтобы определить, что компилятор построит. Код в этом решении написан таким образом, потому что это огромный проект с 400 проектами на разных языках, ассемблере, C, C ++, C #, сценариях и т. Д. Он должен компилироваться на 9 различных платформах и может быть как собственным, так и кросс-компилированный, поэтому он в значительной степени полагается на код генерации кода и конкретный код платформы, который контролируется препроцессором. Я спрашиваю, существует ли инструмент, который будет использовать grep для всех #define, а затем создать поле для их сброса, используя общий макрос #ifdef #pragma message (состояние "VAR" - blah #else #prgma message НЕ определено #endif. Я уверен, что другие люди, когда они видят строку кода, подобную этой #if (define MONKEY) &&! (define DOG) || RELEASE || (DEBUG && FOG) || NO_TRACE && GOAT и т. Д.

Stefan_Lang

Ну, символы #define полностью игнорируют пространства имен, так что они не защитят вас от nameclashes. Точка в случае: некоторые заголовочные файлы windows?) #определите макросы min и max, которые конфликтуют, например, с std:: valarray:: min () и std:: valarray:: max () (не уверен, что это все еще так с VS2015)

Что касается grepping all #defines, то я уже указывал выше, как это даст вам тысячи символов, определенных в системных заголовках в дополнение к тем, которые определены в ваших проектах. У меня есть серьезные сомнения, что вы найдете это полезным.

Однако если ваша цель состоит в том, чтобы выяснить, какой код на самом деле включен в вашу сборку, то просто отправьте свой код через препроцессор без компиляции. В VS это должно быть возможно с помощью переключателя /P-см. http://stackoverflow.com/questions/277258/how-do-i-see-a-c-c-source-file-after-preprocessing-in-visual-studio для получения дополнительной информации.

marcus obrien

Привет, у меня нет конфликтующих именных символов, так что меня это совершенно не волнует. Я нигде не упоминал, что хочу проверить, не конфликтуют ли где-нибудь имена. Я снова хочу поместить все имена препроцессоров #define в один файл. Я не добавляю и не изменяю какое-либо существующее поведение, я проверяю значение #defines. И нет, мне не нужны системные файлы (опять же, я никогда не упоминал об этом). Итак, я хочу просмотреть весь код (а не только файлы заголовков), который мы написали (исключая весь системный код и код, поставляемый с C ++), и скопировать все #define в один файл. (так что не меняйте какой-либо источник - так что проблем с конфликтами имен - поскольку я ничего не меняю) и ПРОТЕСТИРУЙТЕ значение, т.е. #ifdef #pramga message "THE VAR IS ON" #else #pramga message "THE VAR IS OFF "#endif. Так что никаких проблем с конфликтами имен где-либо (поскольку я не буду извлекать имя std :: valarray :: min () или std :: valarray :: max (), поскольку они не #defines), и никаких проблем с миллионами системы определяет (так как я буду искать только в папках, которые мы создали из проверенного репозитория.

marcus obrien

Спасибо Стефану за ссылку, теперь я вижу опцию внутри VS, где вы можете щелкнуть правой кнопкой мыши (контекстное меню) на файле .cpp, затем Свойства, C++, препроцессор, процесс в Файл -> Да. Затем перейдите в выходную папку и изучите файл. i

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

Albert Holguin

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