Компилятор VC++:Как определить текущий уровень предупреждения или переопределения?
-
13-09-2019 - |
Вопрос
У меня есть проект, в котором я только что обнаружил, что предупреждение C4244 (возможная потеря данных) подавляется.Я сильно подозреваю, что какой-то убогий заголовок MS подавляет это предупреждение и оставляет его подавленным для всех единиц перевода, которые включают указанный заголовок, но я не определил, какой из их множества заголовков может быть виноват.
Итак, как и любая другая проблема программирования, я хотел бы начать с выполнения двоичного поиска, распечатки текущего уровня предупреждения и, если возможно, любых подавленных предупреждений в моем основном предварительно скомпилированном заголовке.
Кто-нибудь знает, какую директиву компилятора я мог бы использовать, или какой подход я мог бы использовать, который дал бы мне эту информацию?
Я не могу передать вам, насколько неприятно обнаружить, что мои тщательно сконструированные объявления типов в моих заголовках не выдают предупреждение компилятора, когда вызывающий абонент нарушает контракт и пытается отправить мне целое число вместо байта со знаком (что привело к текущей ошибке, которую я пытаюсь устранить).
Мысли?
Примечания:
Поиск по #pragma во всем моем решении приводит только к сбалансированным объявлениям #pragma warning (отключить: xxxx), за которыми следует #pragma warning (по умолчанию: xxxx).И ни один из них не ссылается на 4244.
Поиск по 4244 во всем решении не возвращает совпадений (я никогда не отменяю это предупреждение, как и любая из моих включенных библиотек, подпроектов и т.д.).
Поиск по 4244 на протяжении всей MS include paths возвращает несколько ссылок, которые появиться быть сбалансированным или почти сбалансированным, в зависимости от символов #define, которые были установлены перед их вызовом.Отсюда мое подозрение, что виновата MS (в сочетании с предыдущей историей MS, выполняющей неаккуратную работу в своих заголовках).
Решение 4
После дальнейшего расследования:
/P занимает слишком много времени (я никогда не видел, чтобы он превышал несколько файлов в течение почти часа, поэтому я отменил эту сборку)
Мне так и не удалось найти четкий способ распечатать текущий уровень предупреждений или какие-либо переопределения, действовавшие в данный момент компиляции.Таким образом, на вопрос, который я задал, на самом деле нет ответа, если только аргумент /P действительно вам не пригодится (как я уже упоминал, для моих целей он был непрактичен).
Что мне удалось сделать, так это создать несколько встроенных вызовов в различных заголовках, которые должны генерировать необходимое предупреждение, если уровень предупреждения включает это предупреждение как активное, чтобы проверить, было ли это предупреждение активным или нет:
встроенный int test (значение символа) { return ++value;}
включить «что-то»
inline int test1(int value) { return test(value);} // должен сгенерировать C4244 — возможна потеря данных, если предыдущий #include не испортил уровень предупреждения или не переопределил предупреждение 4244.
И так далее...
В конце концов я обнаружил, что с 4244, в частности, связаны некоторые странные правила, и что он фактически «отключен» во всех случаях, кроме /W4 (уровень предупреждения 4) — самого высокого уровня предупреждения.Поскольку этот уровень предупреждений очень, очень обидчив и жалуется на множество вещей, которые выходят далеко за рамки наших возможностей что-либо предпринять, я не хотел включать /W4.
Вместо этого я поместил в наш PCH stdafx.h следующее:
pragma alert(error:4244) // это полностью включает предупреждения о возможной потере данных из-за неявного преобразования типов при любых обстоятельствах, независимо от активного уровня предупреждения.
Это сработало.
Таким образом, MS не оставила переопределения несбалансированных предупреждений ни в одном из своих файлов, которые нас затронули.Просто 4244 очень снисходителен, за исключением самого высокого уровня предупреждения, где он в любом случае становится для нас действительно полезным.
Спасибо за вашу помощь!
Другие советы
Другой вариант - добавить это
#pragma warning (defualt)
в верхней части файла сразу после #include
s
Это сбрасывает предупреждение по умолчанию, отбрасывая любое игнорирование, которое могло быть вызвано.
С другой стороны, я нахожу крайне маловероятным, что заголовок Microsoft отключит предупреждение.
Можете ли вы просто выполнить поиск по всем файлам заголовков по запросу «C4244» или у вас есть доступ только к предварительно скомпилированным файлам заголовков?
Вы можете начать с использования Параметр командной строки компилятора /P.Он выводит в файл выходные данные препроцессора.таким образом вы действительно можете убедиться, что это действительно заголовок, который добавляет отключение предупреждения, и попытаться собрать некоторые подсказки относительно того, какой это может быть заголовок.