Приведение аргумента функции указателя NULL привело к нарушению правила Misra 11.3.

Я определяю NULL_PTR как 0U

Затем вызовите функцию с этим NULL_PTR в качестве аргумента.

read_some_data(2U, (uint8_t *const) NULL_PTR, (uint8_t *const) NULL_PTR);

Прототип вызываемой функции:

int16_t read_some_data(const uint8_t id,   uint8_t *const data_1, uint8_t *const data_2);

При компиляции Misra выдала ошибку нарушения правила 11.3 (приведение не должно выполняться между типом указателя и целочисленным типом).

Но если я просто передам NULL_PTR следующим образом, нарушения нет.

read_some_data(2U, NULL_PTR, NULL_PTR);

Как лучше поступить? Подавить правило Misra 11.3 или просто пройти NULL_PTR без кастинга?


person Ammamon    schedule 28.03.2011    source источник
comment
NULL_PTR должен быть определен как (void *)0. Обратите внимание, что это отличается от C++, где вы можете просто определить его как 0.   -  person Paul R    schedule 28.03.2011
comment
@ Пол Р. почему? 0u является константой нулевого указателя как в C, так и в C++. (void*)0 является константой нулевого указателя в C, но не в C++. Неясно, предназначено ли NULL_PTR иметь тип указателя или быть нулевой константой указателя, поэтому я ничего против не имею, что это (void*)0, но, предположительно, такое определение вызовет срабатывание правила Misra и так что тут все равно не вариант. В C++ он в значительной степени должен быть целым типом, чтобы быть полезным, поскольку нет неявного преобразования из void* в другие типы указателей, поэтому (void*)0 нельзя присвоить без приведения.   -  person Steve Jessop    schedule 28.03.2011
comment
AFAIK, основная проблема с тем, что он имеет целочисленный тип, а не тип указателя, заключается в том, что происходит, когда вы по глупости используете его в varargs без приведения, потому что люди ошибочно думают, что знают, какой тип имеет NULL, и с большей вероятностью ошибочно думают, что это указатель, чем ошибочно думают, что это именно int, а не другой целочисленный тип. Если Misra запрещает кастинг, то вы в значительной степени облажались, вам придется создать временную переменную-указатель, чтобы содержать значение. То же самое относится и к непрототипным вызовам функций, но, конечно же, Misra запрещает и их?   -  person Steve Jessop    schedule 28.03.2011
comment
Что за глупое правило Misra 11.3, если оно запрещает (void *)0? Это выражение гарантировано создает константу нулевого указателя.   -  person u0b34a0f6ae    schedule 08.11.2011
comment
MISRA не запрещает кастинг, но 0u — это не указатель, а целая величина. @PaulR прав!   -  person Andrew    schedule 06.08.2015


Ответы (4)


Что не так со стандартным «NULL»?

person fizzer    schedule 28.03.2011
comment
Приводит ли это в действие правило Мишры? Реализациям C разрешено (и действительно часто) определять NULL как (void*)0, что является приведением между указателем и целочисленным типом... - person Steve Jessop; 28.03.2011

Зачем бросать, если можно этого избежать? Cast всегда делает код немного более грязным и намекает на то, что в нем есть что-то хакерское.

Поэтому я бы просто передал NULL_PTR без приведения. После проверки спецификации функции она может принимать NULL_PTR в качестве второго параметра!!!

person Alexander Poluektov    schedule 28.03.2011

Я использовал NULL_PTR в своем заголовочном файле, чтобы избежать использования внутреннего файла конфигурации IAR yvals.h, который определяет NULL. Но это не проблема, так как мне, возможно, придется использовать yvals.h позже по другим причинам.

Независимо от того, используете ли вы NULL или NULL_PTR, я предполагаю, что общий консенсус заключается в передаче NULL без приведения. У моей функции нет проблем с ее принятием. Таким образом, я могу избежать подавления правила Misra 11.3.

Надеюсь, я иду правильным путем.

person Ammamon    schedule 29.03.2011
comment
Я не могу определить NULL_PTR как (void*)0U, так как это снова нарушает правило Misra 11.3. Я оставил 0U и прошел NULL_PTR без приведения. - person Ammamon; 29.03.2011

При компиляции Misra выдала ошибку нарушения правила 11.3.

Чтобы быть педантичным, MISRA не выдавала ошибку нарушения, ваш компилятор выдавал ошибку нарушения правила MISRA C:2004.

Из того, что вы опубликовали, я не уверен, что сообщение о нарушении верно...

С другой стороны, лично я бы определил NULL_PTR как (void *)0u, потому что (строго говоря) 0 не является указателем.

--

Для MISRA C:2004 правило 11.3 является рекомендательным, предоставляя рекомендацию... Правило также говорит, что эта ситуация может быть неизбежной. Таким образом, нарушение может быть проигнорировано (с обоснованием). При применении соответствия требованиям MISRA правило может быть отменено.

В качестве альтернативы эквивалентное руководство в более новой версии, правило 11.4 MISRA C: 2012, имеет явное исключение для константы нулевого указателя.

person Andrew    schedule 27.09.2012