Вот код, как показано ниже:
std::stringstream os;
os << std::hex; // MISRA warning on this line
os << std::setw(2);
os << std::setfill('0');
Предупреждение: «Обязательное правило 8-4-4, идентификатор функции используется без»&’или список параметров в скобках «
Я не могу решить эту проблему, пожалуйста, предложите решение.
Сделайте то, что говорит предупреждение: возьмите адрес функции:
os << &std::hex;
Как насчет просто использования &
как предложил?
#include <iomanip>
#include <iostream>
#include <sstream>
int main() {
std::stringstream os;
os << &std::hex; // Works with &
os << std::setw(2);
os << std::setfill('0');
os << 13;
std::cout << os.str() << "\n";
return 0;
}
Да, это тоже работает.
В чем разница ?
std::hex
это ссылка функционировать&std::hex
это указатель функционироватьПоскольку ссылки на функцию имеют неявное преобразование в указатели на функцию, вы можете передать либо ostream
и это будет работать как положено. Тем не менее, очевидно, что MISRA требует от вас явного Я хочу функцию или же Я хочу вызвать функцию.
Ты можешь сделать
std::hex(std::cout);
что эквивалентно
std::cout << std::hex;
Который избавится от предупреждения. В качестве альтернативы используйте
std::cout << &std::hex;
но это выглядит действительно некрасиво, хотя и правильно.
Суть в том, что MISRA здесь «неправильный» / неловкий / неожиданный. std::hex
может быть использован, как вы сделали без каких-либо проблем.
Линия
os << std::hex;
в конечном итоге вызывает перегрузку
basic_ostream<charT,traits>& basic_ostream::operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&))
который является operator<<()
перегрузка, которая принимает указатель на функцию с basic_ostream<>
аргумент. Ничего не поделаешь std::hex
это здесь.
Тот operator<<()
Перегрузка просто вызывает функцию через указатель. Таким образом, вы можете сделать любое из следующих действий, которые эквивалентны:
os << &std::hex; // makes the function pointer explicit using the & operator
std::hex(os); // call the `std::hex` function using a normal function call syntax
// or directly call the function that `std::hex(os)` is specified to do:
os.setf(std::ios_base::hex, std::ios_base::basefield);
Жаль, что MISRA жалуется на идиоматический способ установки выходного потока в шестнадцатеричное форматирование.
Может быть, это не по теме, но остерегайтесь использования std :: stringstream и потоков в целом. У него есть состояние и по умолчанию он не выдает. Так, в случае нехватки памяти, он просто устанавливает флаг «error» вместо бросания std :: bas_alloc, который может быть источником очень сложных ошибок и сбоев.
проверять http://www.cplusplus.com/reference/ios/ios/exceptions/
Прежде всего, код, который вы показали, выглядит вполне стандартным для меня.
Я вижу некоторые возможные объяснения и способы решения этой проблемы соответственно:
Ручной манипулятор std::hex
реализован в соответствии с MISRA.
а) не использовать std::hex
,
б) исправить std::hex
, Попробуйте поискать реализацию std::hex
в вашей среде.
Код, включающий std :: hex, соответствует, но предупреждение ошибочное.
а) Игнорировать или подавить предупреждение.
б) Подайте отчет об ошибке с поставщиком вашего компилятора или валидатора кода.
У вас действительно есть три варианта:
std::hex
cout<<&std::hex
Первый вариант может быть непрактичным, второй — неприглядным.
К счастью, стандарты MISRA предполагают, что правила не будут рабски соблюдаться — от стандарта MISRA C (который является единственным, для которого у меня есть текст, который нужно передать)
Строгое соблюдение всех правил маловероятно, и на практике допустимы отклонения, связанные с отдельными ситуациями.
Это, конечно, не означает, что вы можете делать то, что хотите, вместо этого стандарт ожидает запрос на отклонение будет представлен — как это делается, является локальным вопросом, и ваша СМК должна покрыть это. С точки зрения вашего инструмента, может быть возможность игнорировать для каждого случая.