Как вставить элементы в std::map, не нарушая MISRA C++ 2008 Required Rule 5-2-12?

Я получаю эту ошибку в PC-Lint (au-misra-cpp.lnt):

ошибка 1960: (Примечание. Нарушает обязательное правило MISRA C++ 2008 5-2-12, тип массива передается функции, ожидающей указатель)

В этом коде:

_IDs["key"] = "value";

_ID объявляется как:

std::map<std::string,std::string> _IDs;

также пытался изменить на:

_IDs.insert("key","value");

Но получить ту же ошибку.

Как сделать код совместимым с мисрой?


person MathiasWestin    schedule 31.05.2013    source источник
comment
Есть ли у MISRA что-то, что можно сказать о неиспользовании зарезервированных имен? Если нет, то стандарт С++, безусловно, делает это.   -  person Mike Seymour    schedule 31.05.2013
comment
Да, он не любит подчеркивания. Нарушает обязательное правило MISRA C++ 2008 17-0-2, повторное использование шаблона идентификатора C++.   -  person MathiasWestin    schedule 31.05.2013


Ответы (2)


Нарушенное правило вызывает std::string::string(const CharT* s, const Allocator& alloc = Allocator()), который будет распадаться от char const [] до указателя на символ.

Решение, я думаю, состоит в том, чтобы явно указать тип указателя:

_IDs[static_cast<char const *>("key")] = static_cast<char const *>("value");

Тем не менее, я бы посоветовал не использовать (или, по крайней мере, обновлять) линтер, который предупреждает, когда вы действительно используете std::string.

Также обратите внимание, что вы не можете вызывать std::map::insert так, как пытаетесь это сделать. Нет перегрузки, которая принимает ключ и значение напрямую, вместо этого есть перегрузка, которая принимает пару, состоящую из ключа и значения. См. здесь перегрузку номер 1.

person slaphappy    schedule 31.05.2013
comment
Очевидно, что после MISRA получается более легкий для чтения и простой в обслуживании код :-P - person Angew is no longer proud of SO; 31.05.2013
comment
@Angew: цель MISRA — сделать код сложнее для чтения и обслуживания. Таким образом, маловероятно, что сопровождающий будет думать, что понимает код, и внесет критические изменения, основываясь на неполных знаниях. Преобразовывая код в тарабарщину, MISRA требует полного анализа, прежде чем вносить даже самые маленькие изменения. Следовательно, более стабильный код. - person Mike Seymour; 31.05.2013
comment
@MikeSeymour Интересный подход. Тем не менее, я бы сказал, что это также усложняет просмотр/проверку кода. Тем не менее, я (отчасти) понимаю, о чем вы говорите. - person Angew is no longer proud of SO; 31.05.2013
comment
Статическое приведение обрабатывает нарушение 5-2-12. - person MathiasWestin; 31.05.2013
comment
@Angew: Опять же, усложняя эти вещи, запутывание, вызванное MISRA, заставляет рецензентов анализировать код в мучительных деталях. Нет никакого соблазна затушевывать те части, которые заведомо верны, так как нет ничего очевидного. Это было бы безумием для большинства разработчиков программного обеспечения; но для критически важного для безопасности кода вам нужно рассматривать каждую строку как потенциально враждебную, и сделать каждую строку нечитаемой — один из способов добиться этого. - person Mike Seymour; 31.05.2013
comment
@MikeSeymour: я в замешательстве - ты не был саркастичным? - person Michael Burr; 31.05.2013
comment
@MichaelBurr: я был наполовину саркастичен; но это, кажется, единственное реальное оправдание для заявления о том, что куча безумно ограничивающих правил может повысить надежность программного обеспечения. (Конечно, это также служит для подавления любого потенциального творчества разработчиков, что также может привести к меньшему количеству ошибок.) Отказ от ответственности: я не пишу код, критически важный для безопасности, и никогда не сталкивался с подобными правилами на собственном опыте. - person Mike Seymour; 31.05.2013

// a template function that takes an array of char 
//  and returns a std::string constructed from it
//
// This function safely 'converts' the array to a pointer
//  to it's first element, just like the compiler would
//  normally do, but this should avoid diagnostic messages
//  from very restrictive lint settings that don't approve
//  of passing arrays to functions that expect pointers.
template <typename T, size_t N>
std::string str( T (&arr)[N])
{
    return std::string(&arr[0]);
}

Используя приведенную выше функцию шаблона, вы сможете обойти линтер следующим образом:

_IDs[str("key")] = str("value");

Кроме того, я удивлен, что lint не жалуется на то, что _IDs является зарезервированным именем - вам следует избегать подчеркивания в начале в C или C++, особенно при использовании вместе с заглавными буквами.

person Michael Burr    schedule 31.05.2013