Любая утилита для тестирования расширения C / C ++ # определения макросов? - PullRequest
32 голосов
/ 11 июня 2010

Кажется, я часто трачу слишком много времени, пытаясь заставить макрос #define делать именно то, что я хочу. Я опубликую свою текущую дилемму ниже, и любая помощь приветствуется. Но на самом деле главный вопрос в том, может ли кто-нибудь порекомендовать какую-либо утилиту для быстрого отображения того, что на самом деле делает макрос? Кажется, что даже медленный процесс проб и ошибок пошел бы намного быстрее, если бы я мог видеть, что не так.

В настоящее время я динамически загружаю длинный список функций из созданной мной DLL. Как я установил, указатели на функции имеют те же номера, что и экспортируемые функции, а typedef (s), используемые для их прототипирования, имеют те же имена, но с добавлением подчеркивания. Поэтому я хочу использовать определение, чтобы упростить назначения длинного длинного списка указателей функций.

Например, в приведенной ниже инструкции кода «hexdump» - это имя точки функции typedef, а также имя функции, тогда как _hexdump - это имя typedef. Если GetProcAddress () завершается ошибкой, счетчик ошибок увеличивается.

if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;

Допустим, я хотел бы заменить каждую строку, как указано выше, макросом, например так ...

GETADDR_FOR(hexdump )

Ну, это лучшее, что я придумал до сих пор. Это не работает (мой // комментарий только для предотвращения форматирования текста в сообщении) ...

// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail; 

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

Ответы [ 5 ]

25 голосов
/ 05 июля 2017

enter image description here Перейдите к https://godbolt.org/. Введите свой код в левой панели и выберите компилятор, так как gcc поместит аргумент как -E в правой панели. Ваш предварительно обработанный код появится справа.

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

Вы можете просто запустить свой код через препроцессор, который покажет вам, во что он будет расширен (или, при необходимости, выложит ошибки):

$ cat a.c
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) 
GETADDR_FOR(hexdump)

$ gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
a.c:1:36: error: '#' is not followed by a macro parameter

GETADDR_FOR(hexdump)

В GCC это только 1004Предварительная обработка файла.

Visual Studio использует аргумент /P.

6 голосов
/ 06 августа 2012

http://visualstudiogallery.msdn.microsoft.com/59a2438f-ba4a-4945-a407-a1a295598088 - плагин Visual Studio для расширения макросов

2 голосов
/ 11 июня 2010

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

Вам может пригодиться эта страница о макросах препроцессора C в целом *.

В частности, я думаю, что этот макрос должен выглядеть следующим образом:

#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail

Конечный ; должен быть пропущен, потому что вы, вероятно, наберете это как GETADDR_FOR(hexdump);, и если вы неЭто не будет выглядеть очень странно в вашем коде C и запутает многие подсветки синтаксиса.

И, как кто-то еще упомянул, gcc -E запустит препроцессор и пропустит другие шаги компиляции.Это полезно для отладки проблем препроцессора.

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

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

...