2015-07-10 4 views
1

Рассмотрим следующий код:Discover, если инициализация структуры не изменяет всех членов

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 
}; 

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

+0

Любой, кто имеет какие-либо советы таким образом? – user2448122

ответ

1

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

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

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

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

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

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

+0

Спасибо за подробный ответ. Я играю с параметрами [-Wmissing-field-initializers] gcc (так как это возможно для компиляции кода с gcc), но он дает мне ложные положительные предупреждения. См. [Link] (http://stackoverflow.com/questions/22194935/wmissing-field-initializer-when-using-designated-initializers). -Унициализация не является вариантом, так как эти инициализации помещаются в верхнюю часть источников (глобальная область). Я рассмотрю инструмент Atlas (мы используем Eclipse CDT для разработки), поскольку это может быть интересно ... – user2448122

+0

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

+0

Уже можно распознать недостающие инициализаторы с помощью нашего инструмента, хотя ... был определен узел GlobalVariable, который помечен как «## tentative-definition-only» (без 'extern'), но не инициализирован, тогда как локальный (стек) переменная, которая не была инициализирована, имеет неинициализированное значение, текущее к ней. Края TypeOf могут использоваться для распознавания структур или экземпляров конкретной структуры по мере необходимости. –