техника для отладки макросов в C - PullRequest
0 голосов
/ 01 января 2011

Итак, у меня есть (в основном очерченный) #define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) ) где-то в программе (да, да, я знаю). В некоторый момент в коде есть сравнение X>-1?, где X (насколько я могу судить) - целое (со знаком). Строка j += MAX(bmGs[i], bmBc[(int)y[i + j]] - m + 1 + i);, где y здесь char*. Не обязательно удивительно, я обнаружил, что макрос возвращает -1 как большее число (я предполагаю, что слишком длинное число для int или unsigned проблемы, но я не могу его найти). Ребята, я хотел бы знать, какие у вас могут быть методы поиска ошибок такого рода.

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

Спасибо.

Ответы [ 3 ]

4 голосов
/ 01 января 2011

Я думаю, что ваша проблема может заключаться в том, что стандартный C будет сравнивать целое число со знаком и целое число без знака, выдвигая -1 к количеству без знака (сохранение значения вместо сохранения знака), что, в свою очередь, означает, что X никогда не больше, чемконвертируется -1, и сравнение всегда ложно.Если я прав, макрос - красная сельдь;проблема не в макросе как таковом (который написан правильно и работает нормально, если типы являются разумными, и ни один из аргументов не имеет побочных эффектов).

Является ли этот код поиском строк Бойера-Мура, как описано Кристиан Чаррас и Тьерри Лекрок ?

Если bmG не подписан, но bmBc подписан или наоборот, у вас возникнут проблемы, но оба массива в оригинале являются целыми числами со знаком.

3 голосов
/ 01 января 2011

Если вы используете GCC, скомпилируйте с флагом "-E" (это capital"E").Это запустит только этап препроцессора, отправив вывод на стандартный вывод, а затем остановится.

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

2 голосов
/ 02 января 2011

Я думаю, что один из ваших m или i - это size_t или что-то в этом роде? Тогда второй аргумент макроса MAX тоже равен size_t. Возможно, это таким образом оценивается как (size_t)-1?

В любом случае этот код выглядит подозрительно. Индексные массивы, такие как y[], которые вы должны будете преобразовать от char до int, пахнутые слабым шрифтом. Индексирование с помощью char без учета возможных проблем с подписью просто опасно. Типы индексов всегда должны быть типами без знака.

Макрос, подобный вашему MAX, который подразумевает, что оба выражения имеют одинаковую подпись и ширину, также опасен. Замените его на функцию intmax_t MAX(intmax_t, intmax_t) или что-то в этом роде.

Правильно переработайте типы, и ваша проблема решится сама собой.

clang как компилятор достаточно хорош для отладки макросов. Кроме gcc, например, он может следить за расширением макросов и иногда может решить проблему с макросом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...