Предположим, я пишу интерпретатор, и одна из его команд имеет вид
define variable
где переменная может быть только строчной латинской буквой.
Вот что я делаю. Определив, что команда является определенной командой, я создаю поток из строки, скажем, "define a"
(iss), затем прочитайте имя команды из нее, подтвердите, что это действительно «определение».
std::istringstream iss(Command);
//read the word "define"std::string cmdstr;
assert(iss >> cmdstr);
assert(cmdstr == DefineStr);
Затем я читаю персонаж из потока. Чтение должно быть успешным, поэтому я проверяю
if(!(iss >> var))
{
errorMsg = "Invalid syntax of define command. Too few arguments\n";
return false;
}
Затем я должен проверить, что в потоке больше нет непробельных символов, поэтому я проверяю
//the rest of the line must be empty;
if(iss >> var)
{
errorMsg = "Invalid syntax of define command. Too many arguments\n";
return false;
}
Моя стратегия тестирования заключается в том, что в потоке больше персонажей неправильно? Я знаю, что мог бы использовать регулярные выражения, анализаторы духа и еще много чего, чтобы решить эту проблему, но предположим, что я хочу придерживаться этого подхода. Проблема в том, что в режиме отладки (MSVC10.0) функция работает, как и ожидалось, когда я ввожу define a
тогда как в режиме Release функция как-то попадает в if(iss >> var)
и говорит Invalid syntax of define command. Too many arguments
, Я застрял, я не могу понять, что не так.
Полный код функции выглядит следующим образом:
bool Interpreter::ExecuteDefineCommand(const std::string& Command, std::string& errorMsg)
{
std::istringstream iss(Command);
//read the word "define"std::string cmdstr;
assert(iss >> cmdstr);
assert(cmdstr == DefineStr);
//read the variable name
char var;
if(!(iss >> var))
{
errorMsg = "Invalid syntax of define command. Too few arguments\n";
return false;
}
if(!islower(var))
{
errorMsg = "You may define only lowercase variables\n";
return false;
}
//the rest of the line must be empty;
if(iss >> var)
{
errorMsg = "Invalid syntax of define command. Too many arguments\n";
return false;
}
auto insertRes = variables.insert(std::make_pair(var, 0));
if(!insertRes.second)
{
errorMsg = "The variable ";
errorMsg += var;
errorMsg += " has already been defined!\n";
return false;
}
return true;
}
Проблема здесь:
std::string cmdstr;
assert(iss >> cmdstr);
assert(cmdstr == DefineStr);
Поскольку operator >> находится внутри assert, он просто не выполняется в режиме Release! Правильный подход будет
std::string cmdstr;
iss >> cmdstr;
assert(iss);
assert(cmdstr == DefineStr);
Других решений пока нет …