Мне нравится различать три разных типа конфликта от системы управления версиями (VCS):
- текстовые
- синтаксический
- семантическая
Текстовый конфликт - это тот, который определяется процессом слияния или обновления. Это помечено системой. Конец результата не разрешен VCS до тех пор, пока конфликт не будет разрешен.
Синтаксический конфликт не помечен VCS, но результат не будет компилироваться. Поэтому это следует также поднять даже слегка осторожным программистом. (Простым примером может быть переименование переменной слева и некоторыми добавленными строками с использованием этой переменной справа. Слияние, вероятно, будет иметь неразрешенный символ. В качестве альтернативы это может привести к смысловому конфликту при смене переменной.)
Наконец, семантический конфликт не отмечен VCS, результат компилируется, но у кода могут быть проблемы с запуском. В мягких случаях производятся неправильные результаты. В тяжелых случаях может произойти авария. Даже они должны быть обнаружены перед фиксацией очень осторожным программистом посредством проверки кода или тестирования модулей.
Мой пример семантического конфликта использует SVN (Subversion) и С++, но эти варианты не имеют отношения к сути вопроса.
Базовый код:
int i = 0;
int odds = 0;
while (i < 10)
{
if ((i & 1) != 0)
{
odds *= 10;
odds += i;
}
// next
++ i;
}
assert (odds == 13579)
Изменения Left (L
) и Right (R
) следующие.
Левая оптимизация (изменение значений, которые принимает переменная цикла):
int i = 1; // L
int odds = 0;
while (i < 10)
{
if ((i & 1) != 0)
{
odds *= 10;
odds += i;
}
// next
i += 2; // L
}
assert (odds == 13579)
Правая "оптимизация" (изменение способа использования переменной цикла):
int i = 0;
int odds = 0;
while (i < 5) // R
{
odds *= 10;
odds += 2 * i + 1; // R
// next
++ i;
}
assert (odds == 13579)
Это результат слияния или обновления и не обнаруживается SVN (это правильное поведение для VCS), поэтому это не текстовый конфликт. Обратите внимание, что он компилируется, поэтому он не является синтаксическим конфликтом.
int i = 1; // L
int odds = 0;
while (i < 5) // R
{
odds *= 10;
odds += 2 * i + 1; // R
// next
i += 2; // L
}
assert (odds == 13579)
assert
терпит неудачу, потому что odds
равен 37.
Итак, мой вопрос таков. Есть ли более простой пример? Есть ли простой пример, когда скомпилированный исполняемый файл имеет новый сбой?
В качестве второстепенного вопроса есть случаи, с которыми вы столкнулись в реальном коде? Опять же, простые примеры особенно приветствуются.