如何在不违反MISRA C++ 2008咨询规则5-2-10的情况下使用std :: transform?

Mat*_*tin 1 c++ misra

我在PC-Lint中遇到这些错误(au-misra-cpp.lnt):

ConverterUtil.cpp(90):错误864 :(信息 - 涉及变量'transformValue'的表达式可能取决于评估顺序[ MISRA C++规则5-2-10 ])

ConverterUtil.cpp(90):错误864 :(信息 - 涉及变量'transformValue'的表达式可能取决于评估顺序[ MISRA C++规则5-2-10 ])

ConverterUtil.cpp(90):错误534 :(警告 - 忽略函数'std :: transform(std :: _ St​​ring_iterator >>,std :: _ St​​ring_iterator >>,std :: _ St​​ring_iterator >>,int(*))的返回值(int))'(与第998行,文件C:\ Program Files(x86)\ Microsoft Visual Studio 11.0\VC\include\algorithm)比较[MISRA C++规则0-1-7和8-4-6],[ MISRA C++规则0-3-2])

在这段代码上:

/**Conversion from std::string to bool*/
bool ConverterUtil::ConvertStdStringToBool(const std::string value)
{
    std::string transformValue = value;
    bool retValue = false;

    std::transform(transformValue.begin(), transformValue.end(), transformValue.begin(), &::tolower);


    if(transformValue == std::string(static_cast<const char *>("true")))
    {
        retValue = true;
    }

    return retValue;
}
Run Code Online (Sandbox Code Playgroud)

我猜测它不喜欢我在转换中使用相同的std :: string作为输入和输出这一事实,但是使用其他字符串作为输出会产生相同的错误.

是否可以使std :: transform MISRA兼容?

Cas*_*eri 5

我只是在这里猜测(如果它没有解决你的问题,我可能会删除答案).

尝试std::transform用这两个替换包含行:

auto dest = transformValue.begin();
std::transform(transformValue.cbegin(), transformValue.cend(), dest, &::tolower);
Run Code Online (Sandbox Code Playgroud)

注意使用cbegin()cend()(而不是begin()end()).

另一个话题:ConvertStdStringToBool当你只做一次时,你正在复制传递给它的字符串两次.为此,请替换:

bool ConverterUtil::ConvertStdStringToBool(const std::string value)
{
    std::string transformValue = value;
Run Code Online (Sandbox Code Playgroud)

bool ConverterUtil::ConvertStdStringToBool(std::string transformValue)
{
Run Code Online (Sandbox Code Playgroud)

(您可能希望在此更改后重命名transformValuevalue).

更新:我的解释为什么我认为它会有所帮助.

首先,请注意transformValue不是const.因此,transformValue.begin()transformValue.end()将调用这些重载:

iterator begin(); // non const overload
iterator end();   // non const overload
Run Code Online (Sandbox Code Playgroud)

因此,静态分析器(正确地)得出结论begin()并且end()可能改变状态transformValue.在这种情况下,最终状态transformValue可能取决于第一个begin()end()第一个被调用.

现在,当你调用cbegin()cend(),重载是这些:

const_iterator cbegin() const; // notice the const 
const_iterator cend() const;   // notice the const
Run Code Online (Sandbox Code Playgroud)

在这种情况下,静态分析器不会推断这些调用将改变状态transformValue并且不会引发问题.(严格地说,即使这些方法const可以改变状态,因为类中可能存在mutable数据成员,或者方法可能使用邪恶const_cast.恕我直言,静态分析器不应该因此而受到指责.)

最后的评论:电话

std::transform(transformValue.cbegin(), transformValue.cend(), transformValue.cbegin(), &::tolower);
                                                                              ^^^^^^
Run Code Online (Sandbox Code Playgroud)

是错的.第三个参数必须是非const迭代器,也就是说,它必须transformValue.begin()(前两个参数是c*方法).

但是,我想,对于与上面类似的推理,仅仅使用transformValue.begin()第三个参数是不够的,这就是我建议创建另一个变量(dest)的原因.