Выясните, не изменяет ли инициализация структуры все элементы

Рассмотрим следующий код:

typedef struct _sMYSTRUCT_BASE
{
    int b_a;
    int b_b;
    int b_c;
} sMYSTRUCT_BASE;

typedef struct _sMYSTRUCT
{
    sMYSTRUCT_BASE base;
    int            a;
    int            b;
} sMYSTRUCT;

Private const sMYSTRUCT mystruct_init =
{
    0,
    1,
    3,
    4
};

Я ищу способ сгенерировать ошибку (компиляцию или время выполнения), чтобы указать, что инициализация структуры явно не «затронула» все элементы структуры. В структуре 5 целых чисел, но 'mystruct_init' имеет только 4 значения. Я знаю, что последний член (mystruct_init.b) будет равен нулю, но мне нужно какое-то предупреждение/ошибка, чтобы сообщить программисту об ошибке. Это должно работать на очень старом компиляторе (возможно, даже не совместимом с ansi-c).


person user2448122    schedule 10.07.2015    source источник
comment
У кого-нибудь есть советы по этому поводу?   -  person user2448122    schedule 05.08.2015


Ответы (1)


Современные компиляторы способны выдавать такое предупреждение... в gcc оно включается параметром -Wmissing-field-initializers (который предупреждает об инициализаторах, которые существуют, но не инициализируют все элементы, но не о структурах без выражения инициализатора; они могут по крайней мере, иногда можно поймать, включив -Wuninitialized, который предупредит вас, если увидит, что вы читаете потенциально неинициализированное значение, по крайней мере, если вы читаете его в той же функции, в которой была объявлена ​​​​переменная).

Если ваш очень старый компилятор выдает такое предупреждение, вы, конечно, можете просто включить его, но судя по вашему описанию, это маловероятно.

Я думаю, что лучшим вариантом для вас, если вы хотите выполнить их исчерпывающий поиск, было бы посмотреть, можете ли вы получить код для компиляции с какой-либо версией gcc - он не должен компилироваться достаточно хорошо, чтобы фактически работать на ваша целевая платформа, чтобы получать предупреждения. Я не могу гарантировать, что он сможет скомпилировать ваш код C до ANSI, особенно если он широко использует специфичные для компилятора расширения, но я могу, по крайней мере, сказать, что поддержка устаревшего синтаксиса K&R все еще присутствует в современном стандарте C. , поэтому я не удивлюсь, если ваш код скомпилируется лучше, чем вы думаете.

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

Другой вариант — посмотреть, сможете ли вы найти совместимый статический анализатор, который может выполнить такую ​​проверку; Я работаю над инструментом под названием EnSoft Atlas, который строит граф потока данных, который вместе с простым скриптом можно использовать для принудительной инициализации более тщательно, чем позволяют предупреждения gcc, проверяя, происходит ли поток неинициализированных значений в поля структур.

Однако наша поддержка C все еще находится в стадии бета-тестирования. Atlas требует, чтобы Eclipse CDT (или JDT для Java) мог анализировать ваш код, а текущая бета-версия C полностью поддерживает только современные строго типизированные инициализаторы структур (т. е. struct foo f = (struct foo) {...} имеет полностью подключенный поток данных, но поддерживает старый синтаксис списка инициализаторов). struct foo f = {...} не был реализован в нашем первом проходе), поэтому я не уверен, что он сможет удовлетворить ваши потребности в настоящее время.

person Theodore Murdock    schedule 15.08.2015
comment
Спасибо за подробный ответ. Я играю с опциями [-Wmissing-field-initializers] gcc (поскольку с помощью gcc можно скомпилировать код), но это дает мне несколько ложных срабатываний. См. ссылку. -Wuninitialized не вариант, так как эти инициализации размещаются в верхней части источников (глобальная область). Я рассмотрю инструмент Atlas (для разработки мы используем Eclipse CDT), так как это может быть интересно... - person user2448122; 17.08.2015
comment
Я внимательно изучил текущий статус нашего инструмента для инициализаторов структур, и он немного менее полон, чем я думал на данный момент. Узлы значений по умолчанию, которые, как я думал, будут присутствовать для отсутствующих полей, еще не реализованы. Я обновлю это, когда они будут добавлены. - person Theodore Murdock; 19.08.2015
comment
Однако с помощью нашего инструмента уже можно распознать отсутствующие инициализаторы... узел GlobalVariable с тегом ##tentative-definitions-only был определен (без extern), но никогда не инициализировался, в то время как локальная (стековая) переменная, которая не была инициализирована имеет неинициализированное значение, поступающее к нему. Ребра TypeOf можно использовать для распознавания структур или экземпляров конкретной структуры по мере необходимости. - person Theodore Murdock; 19.08.2015