Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Intel C++ switch statement bug.

roman_p_
Beginner
560 Views

int i = 0;

switch ( i )

{

case 0:

// some code

i = 1;

break;  // if optimization is disabled everything works as supposed, but if intel optimization is enabled this "break" doesn't exist and execution goes into case 1 body

case 1:

// some code

break;

}

0 Kudos
7 Replies
olzhas_r_
New Contributor I
560 Views
I highly doubt this kind of common code can slip into a bug. I was curious and tried the code, but the bug didn't show up. (on linux with icc 16.0 and gcc 5.4). Can you show more code?
0 Kudos
roman_p_
Beginner
560 Views

I used Parallel Studio XE2013 an XE2016 update 3. Exact code is:

    enum POLYSTATE
    {
        START,
        TOP,
        BOTTOM
    } state = START;
    for (; i < pRgnData->rdh.nCount; ++i)
    {
      switch (state)
      {
      case START:
        {
          pRastrTool->NewLine();
          if (!pRastrTool->AddDscrSeg(pRect.top, pRect.left, pRect.right))
            bErr = true;
          yPrev = pRect.top;
          iStart = i;
          state = TOP;
        } break;
      case TOP:
        {
          if (yPrev == pRect.top)
          {
            if (!pRastrTool->AddDscrSeg(pRect.top, pRect.left, pRect.right))
              bErr = true;
            yPrev = pRect.top;
          }
          else
          {
            i = iStart;
            pRastrTool->NewLine();
            if (!pRastrTool->AddDscrSeg(pRect.bottom, pRect.left, pRect.right))
              bErr = true;
            yPrev = pRect.bottom;
            state = BOTTOM;
          }
        } break;
      case BOTTOM:
        {
          if (yPrev == pRect.bottom)
          {
            if (!pRastrTool->AddDscrSeg(pRect.bottom, pRect.left, pRect.right))
              bErr = true;
            yPrev = pRect.bottom;
          }
          else
          {
            iStart = i;
            if (yPrev == pRect.top)
              pRastrTool->NewLine();
            else
              pRastrTool->Split();
            if (!pRastrTool->AddDscrSeg(pRect.top, pRect.left, pRect.right))
              bErr = true;
            yPrev = pRect.top;
            state = TOP;
          }
        } break;
      }
    }

When any kind of optimization is enabled I can clearly see that "break" is ignored and execution flows into next case body. I had to add extra variable to avoid the issue.  

 

0 Kudos
olzhas_r_
New Contributor I
560 Views

Strange. I couldn't reproduce the fall-through with either ICC, gcc, clang.

I simplified the code to :

#include <iostream>

int main() {

  enum POLYSTATE { START, TOP, BOTTOM } state = START;

  for (int i = 0; i < 10; ++i) {
    switch (state) {
    case START: {
      state = TOP;
      std::cout << "start" << std::endl;
    } break;

    case TOP: {
      state = BOTTOM;
      std::cout << "top" << std::endl;
    } break;

    case BOTTOM: {
      state = TOP;
      std::cout << "bottom" << std::endl;
    } break;
    }
  }
}

 

0 Kudos
roman_p_
Beginner
560 Views

It seems the issue is more complicated. Here is a whole test project attached. It fails when optimization is enabled. But adding extra variable instead of using "state" helps. AddDscrSeg sometimes get called twice per cycle. 

0 Kudos
olzhas_r_
New Contributor I
560 Views

I would recommend taking a look at the generated code.

By the way, does it work as expected with other compilers?

0 Kudos
roman_p_
Beginner
560 Views

It works as expected with visual studio compiler as well with the intel compiler with optimizations disabled. When intel optimization enabled the execution fails.

0 Kudos
roman_p_
Beginner
560 Views

Checked with Clang 3.7. Works fine as well. It strongly seems the bug is intel C++ specific.

0 Kudos
Reply