考虑一下这段代码(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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果它很重要:这是来自用于过滤和修改文档中的单词的家庭作业的代码.document持有文件(以前从文件中读取)
我想介绍一个恶意的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::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);
}
}
SkipAndRestart:
++currentLineNo;
oldEndOfLine = endOfLine + 1;
endOfLine = document_.find('\n', oldEndOfLine);
}
}
Run Code Online (Sandbox Code Playgroud)
目前这是否是一个好的设计选择是无关紧要的.编译器抱怨error C2362: initialization of 'words' is skipped by 'goto SkipAndRestart'
我不明白这个错误.为什么跳过单词初始化很重要,也是错误的?这正是我想要发生的事情,我不希望它做更多工作,只需重新启动血腥循环.继续宏不是或多或少完全相同吗?
Gre*_*ill 19
你正在跳过words数组的构造:
if(line.size() < 2)
goto SkipAndRestart;
std::vector<std::string> words = Utility::split(line);
// ...
SkipAndRestart:
Run Code Online (Sandbox Code Playgroud)
你可能已经使用words后SkipAndRestart:的标签,这将是一个问题.你不要在你的情况下使用它,但是在引入words变量的范围结束之前不会破坏变量,因此就编译器而言,变量仍在使用中.标签.
您可以通过放入words自己的范围来避免这种情况:
if(line.size() < 2)
goto SkipAndRestart;
{
std::vector<std::string> words = Utility::split(line);
// ...
}
SkipAndRestart:
Run Code Online (Sandbox Code Playgroud)
请注意,continue语句跳转到循环的末尾,在实际上无法放置标签的位置.这是在循环内部任何局部变量被破坏之后,但在跳回到循环顶部之前的一个点.