c – 变量初始化之前的Goto导致编译器错误

前端之家收集整理的这篇文章主要介绍了c – 变量初始化之前的Goto导致编译器错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑一下这段代码(VS2008):
void WordManager::formatWords(std::string const& document)
{
    document_ = document;
    unsigned int currentLineNo = 1;

    size_t oldEndOfLine = 0;
    size_t endOfLine    = document_.find('\n');
    while(endOfLine != std::string::npos)
    {
        std::string line = document_.substr(oldEndOfLine,(endOfLine - oldEndOfLine));
        if(line.size() < 2)
        {
            oldEndOfLine = endOfLine + 1;
            endOfLine    = document_.find('\n',oldEndOfLine);
            continue;
        }

        std::vector<std::string> words = Utility::split(line);
        for(unsigned int i(0); i < words.size(); ++i)
        {
            if(words[i].size() < 2)
                continue;
            Utility::trim(words[i],WordManager::delims);
            Utility::normalize(words[i],WordManager::replace,WordManager::replaceWith);

            if(ruleOne(words[i]) && ruleTwo(words[i]))
            {
                std::set<Word>::iterator sWIter(words_.find(Word(words[i])));

                if(sWIter == words_.end())
                    words_.insert(Word(words[i])).first->addLineNo(currentLineNo);
                else
                    sWIter->addLineNo(currentLineNo);
            }
        }
        ++currentLineNo;

        oldEndOfLine = endOfLine + 1;
        endOfLine    = document_.find('\n',oldEndOfLine);
    }
}

如果它很重要:这是来自用于过滤和修改文档中的单词的家庭作业的代码.文档保存文档(以前从文件中读取)

我想介绍一个恶意的goto,因为我认为它在这种情况下实际上更清洁:

void WordManager::formatWords(std::string const& document)
{
    document_ = document;
    unsigned int currentLineNo = 1;

    size_t oldEndOfLine = 0;
    size_t endOfLine    = document_.find('\n');
    while(endOfLine != std::string::npos)
    {
        std::string line = document_.substr(oldEndOfLine,(endOfLine - oldEndOfLine));
        // HERE!!!!!!
        if(line.size() < 2)
            goto SkipAndRestart;

        std::vector<std::string> words = Utility::split(line);
        for(unsigned int i(0); i < words.size(); ++i)
        {
            if(words[i].size() < 2)
                continue;
            Utility::trim(words[i],WordManager::replaceWith);

            if(ruleOne(words[i]) && ruleTwo(words[i]))
            {
                std::set<Word>::iterator sWIter(words_.find(Word(words[i])));

                if(sWIter == words_.end())
                    words_.insert(Word(words[i])).first->addLineNo(currentLineNo);
                else
                    sWIter->addLineNo(currentLineNo);
            }
        }

SkipAndRestart:
        ++currentLineNo;

        oldEndOfLine = endOfLine + 1;
        endOfLine    = document_.find('\n',oldEndOfLine);
    }
}

目前这是否是一个好的设计选择是无关紧要的.编译器抱怨错误C2362:’goto SkipAndRestart’跳过’words’的初始化

我不明白这个错误.为什么跳过单词初始化很重要,也是错误的?这正是我想要发生的事情,我不希望它做更多工作,只需重新启动血腥循环.继续宏不是或多或少完全相同吗?

解决方法

你正在跳过单词数组的构造:
if(line.size() < 2)
        goto SkipAndRestart;
    std::vector<std::string> words = Utility::split(line);
    // ...
SkipAndRestart:

您可以在SkipAndRestart:标签之后使用单词,这可能是个问题.你不要在你的情况下使用它,但是单词变量在引入它的作用域结束之前不会被破坏,所以就编译器而言,变量仍在使用中.标签.

你可以通过在自己的范围内放置单词来避免这种情况:

if(line.size() < 2)
        goto SkipAndRestart;
    {
        std::vector<std::string> words = Utility::split(line);
        // ...
    }
SkipAndRestart:

请注意,continue语句跳转到循环的末尾,在实际上无法放置标签的位置.这是在循环内部任何局部变量被破坏之后,但在跳回到循环顶部之前的一个点.

原文链接:https://www.f2er.com/c/116304.html

猜你在找的C&C++相关文章