Кто продает компоновщик MISRA?Кажется, есть безумная ошибка.
Можете ли вы обойти это, взяв его адрес int (*foo)(int) = tolower;
в области видимости файла?
Редактировать: Мое обоснование:а.это самая глупая вещь, которую я видел в этом десятилетии, так что это может быть ошибкой, ноб.толкание его в крайний регистр (символ, экспортируемый через глобальное имя) может закрыть его.
Чтобы это было правильным поведением, то есть не ошибкой, было бы ошибкой MISRA включить один раз библиотечную функцию, например initialise_system_timer, initialise_watchdog_timer, ..., которая просто ранит мою голову.
Редактировать: Еще одна мысль.Опять же, исходя из предположения, что это ошибка в крайнем случае.
Теория: Может быть, компилятор выполняет как встроенное, , так и , генерируя реализацию функции.Тогда функция (конечно) не вызывается.Таким образом, правила компоновщика видят эту не вызванную функцию.
GNU имеет опции для предотвращения встраивания.Можете ли вы сделать то же самое для этого использования Tolower?Это меняет ошибку?Вы можете выполнить тест с помощью
#define inline /* nothing */
перед включением ctype.h, а затем отменить определение макроса.
Другой тест должен определить:
#define inline static inline
перед включениемctype.h, которая является версией inline, которую я ожидаю.
EDIT2: Я думаю, что есть ошибка, о которой следует сообщить.Я полагаю, у IAR есть обходной путь.Я бы принял их совет.
После ночного сна я сильно подозреваю, что проблема inline int tolower()
, а не static inline int tolower
или int tolower
, потому что это имеет больше смысла.Наличие общедоступной функции, которая не вызывается, похоже, является признаком ошибки в программе.
Даже с документацией все подходы к кодированию имеют свои недостатки.
Я настоятельно поддерживаю OP, я бы не стал менять стандартный заголовочный файл.Я думаю, что есть несколько причин.Например, дальнейшее обновление цепочки инструментов (которая поставляется с новым набором заголовков) разрушает старое приложение, если оно когда-либо будет поддерживаться.Или просто сборка приложения на другом компьютере дает ошибку, объединение двух, по-видимому, правильных приложений может привести к ошибке, ....Ничего хорошего из этого не получится.-100
Используйте #define ...
, чтобы ошибка исчезла.Я не люблю использовать макросы для изменения стандартных библиотек.Это похоже на семена долгосрочной плохой идеи.Если в будущем другая часть программы использует другую функцию с аналогичной проблемой, применение «исправления» ухудшается.Некоторые неопытные разработчики могут взять на себя работу по поддержке кода, и «учится» оборачивать странные кусочки #define
хитрости вокруг #include
- это «нормальная» практика.Компания становится «практикой», чтобы заключить #include <ctype.h>
в странные макро-обходные пути, которые остаются спустя годы после того, как это было исправлено.-20
Используйте параметр компилятора командной строки, чтобы отключить встраивание. Если это работает и семантика верна, то есть включение заголовка и использование функции в двух исходных файлах не приводит к множественной определенной функции, тогда все в порядке. Я ожидаю, что это приведет к ошибке, но это стоит подтвердить как часть сообщения об ошибке. Это расстраивает ловушку для кого-то еще, кто придет в будущем. Если используется другая стандартная библиотечная функция inline
, и по какой-то причине человек должен посмотреть на сгенерированный код, он также не будет включен. Они могут немного сойти с ума, задаваясь вопросом, почему встроенный не соблюдается. Я предполагаю, что причина, по которой они смотрят на сгенерированный код, в том, что производительность критична. По моему опыту, люди потратили много времени, глядя на код, сбитые с толку, прежде чем смотреть на скрипт сборки для программы, которая работает. Если подавление inline используется как исправление, я чувствую, что лучше делать это везде, чем для одного файла. По крайней мере, семантика является последовательной, и могут быть замечены комментарии или документация высокого уровня. Любой, кто использует сценарии сборки в качестве «быстрой проверки», будет иметь согласованное поведение, которое может побудить их взглянуть на документацию. -1 (везде без встроенного) -3 (без встроенного файла)
Фальшиво используйте tolower во втором исходном файле. Это имеет небольшое преимущество в том, что система сборки не «заражена» дополнительными опциями компилятора. Также это небольшой файл, который даст возможность объяснить ошибку, которую можно обойти. Мне это не очень нравится, но мне нравится больше, чем возиться со стандартными заголовками. Моя текущая проблема - это может не сработать. Это может включать две копии, которые компоновщик не может разрешить. Мне нравится, что это лучше, чем странное «взять его адрес и посмотреть, не отключится ли компоновщик» (что, на мой взгляд, является интересным способом проверки крайних случаев). -2
Кодируйте свой собственный tolower. Я не понимаю более широкий контекст приложения. Моя реакция , а не на замену кода для библиотечных функций, потому что я обеспокоен тестированием (и юнит-тестами, которые вводят еще больше кода) и долгосрочным обслуживанием. Я еще больше нервничаю с символьным вводом / выводом, потому что приложение может нуждаться в способности обрабатывать более широкий набор символов, например кодировку UTF-8, и пользовательский tolower будет иметь тенденцию выходить из синхронизации. Это звучит как очень специфическое приложение (отладка на порт), так что я мог справиться. Мне не нравится писать дополнительный код для работы с вещами, которые выглядят как ошибки, особенно если это коммерческое программное обеспечение. -5
Можете ли вы преобразовать ошибку в предупреждение, не потеряв все остальные проверки? Я все еще чувствую, что это ошибка в инструментальной цепочке, поэтому я предпочел бы, чтобы это было предупреждение, а не молчание, чтобы была ловушка для инцидента и некоторой документации, и меньше вероятность появления другой ошибки. В противном случае идти с выключением ошибки. +1 (предупреждение) 0 (ошибка)
Выключение ошибки, по-видимому, теряет «корпоративную осведомленность» о том, что (IMHO) IAR обязан вам объяснением и более долгосрочным исправлением, но это кажется намного лучше, чем возиться с системой сборки, записывая макро-мерзость в соответствии со стандартом библиотеки, или написание собственного кода, который увеличивает ваши расходы.
Это может быть только я, но мне не нравится писать код, чтобы обойти недостатки в коммерческом продукте. Такое ощущение, что именно здесь поставщик должен быть рад возможности оправдать стоимость своей лицензии. Я помню, что Microsoft взимала с нас плату за инциденты, но если проблема оказалась их, инцидент и исправление были бесплатными. Кажется, правильнее всего дать им шанс заработать деньги. В продуктах будут ошибки, так что молча обходить их, не давая им возможности исправить это, тоже кажется менее полезным.