Better, simpler example of 'semantic conflict'?

Posted by rhubbarb on Stack Overflow See other posts from Stack Overflow or by rhubbarb
Published on 2010-03-25T09:59:54Z Indexed on 2010/03/25 10:03 UTC
Read the original article Hit count: 314

Filed under:
|
|

I like to distinguish three different types of conflict from a version control system (VCS):

  • textual
  • syntactic
  • semantic

A textual conflict is one that is detected by the merge or update process. This is flagged by the system. A commit of the result is not permitted by the VCS until the conflict is resolved.

A syntactic conflict is not flagged by the VCS, but the result will not compile. Therefore this should also be picked up by even a slightly careful programmer. (A simple example might be a variable rename by Left and some added lines using that variable by Right. The merge will probably have an unresolved symbol. Alternatively, this might introduce a semantic conflict by variable hiding.)

Finally, a semantic conflict is not flagged by the VCS, the result compiles, but the code may have problems running. In mild cases, incorrect results are produced. In severe cases, a crash could be introduced. Even these should be detected before commit by a very careful programmer, through either code review or unit testing.

My example of a semantic conflict uses SVN (Subversion) and C++, but those choices are not really relevant to the essence of the question.

The base code is:

int i = 0;
int odds = 0;
while (i < 10)
{
    if ((i & 1) != 0)
    {
        odds *= 10;
        odds += i;
    }
    // next
    ++ i;
}
assert (odds == 13579)

The Left (L) and Right (R) changes are as follows.

Left's 'optimisation' (changing the values the loop variable takes):

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)

Right's 'optimisation' (changing how the loop variable is used):

int i = 0;
int odds = 0;
while (i < 5) // R
{
    odds *= 10;
    odds += 2 * i + 1; // R
    // next
    ++ i;
}
assert (odds == 13579)

This is the result of a merge or update, and is not detected by SVN (which is correct behaviour for the 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)

The assert fails because odds is 37.

So my question is as follows. Is there a simpler example than this? Is there a simple example where the compiled executable has a new crash?

As a secondary question, are there cases of this that you have encountered in real code? Again, simple examples are especially welcome.

© Stack Overflow or respective owner

Related posts about version-control

Related posts about conflict