cancel
Showing results for 
Search instead for 
Did you mean: 

Optimization kills the switch statement that I need to use in a function

VRami.1
Associate III

Hi all, how are you?. I'm doing a project with a STM32F103C6 (it has 32KB flash) and I had to activate optimization options to not run out of memory, right now the optimization options is -Og. After activate optimization a function that I have to know the position of a substring and after that I'm trying to use a switch statement that the compiler is killing and obviously I can't but I don't know why.

Here are de function definitions:

void Selec_Opera(char *ent, uint8_t dim)
{
	volatile uint8_t pos = 0;
	volatile uint8_t lugar = 0;
//	uint8_t com[T_COMANDO] = {0};
	pos = strindex(comandos, (char *) eComando);
	for(lugar = 0; T_COMANDO*lugar <= pos; lugar++)
	{
		asm("nop");
	}
	switch(lugar)
	{
	case 0x01:
	{
		 lugar++;
	}
	break;
	case 0x02:
	{
		 lugar++;
	}
	break;
	case 0x03:
	{
		 lugar++;
	}
	break;
	case 0x04:
	{
		 lugar++;
	}
	break;
	case 0x05:
	{
		 lugar++;
	}
	break;
	case 0x06:
	{
		 lugar++;
	}
	break;
	case 7:
	{
		 lugar++;
	}
	break;
	default:
	{
		 lugar = 25;
	}
	break;
	}
}
 
 
volatile uint8_t strindex(char s[], char t[])
{
	uint8_t i, j, k;
	for (i = 0; s[i] != '\0'; i++)
	{
		for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++);
		if (k > 0 && t[k] == '\0')
		return i;
	}
	return -1;
}

and I'm calling Selec_Opera() from main like follows:

  while (1)
  {
	  if(HAL_I2C_Slave_Receive(&hi2c1, eComando, T_COMANDO, HAL_MAX_DELAY) != HAL_OK)
	  {
		  codigoError = 20;
		  Error_Handler();
	  }
	  else
	  {
		  Selec_Opera((char *) eComando, T_COMANDO);
	  }
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

The I2C function is working well, the problem is with the function Selec_Opera(). If you wanna know T_COMANDO is defined as 4 and eComando is the array where I'm storing the received stream.

When the Selec_Opera() function is being executed it can be seen that almost all the switch options are not compiled, some pictures can show correctly what I'm tring to explain.

The following image shows that when I'm doing a debug session the debug file has the text but almost all the "switch" options code hasn't been included in the executable file (I need this)

0693W000002lTcfQAE.png

only option 7 and default are included, I've tried only for test with reduced options and the behavior is the same, only the last numbered option and the default option are included in the code (this can be seen because at left is written the memory position of the instruction)

I've tested the "for" statement and it is working well selecting the position where the string is so I don't know what is happening with the switch.

Can anyone help with this?. Thanks in advance for the help.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

No doubt what is happening here is the compiler realizes cases 0 through 7 are the same, so it simplifies it to the following:

	switch(lugar)
	{
	case 0x01:
	case 0x02:
	case 0x03:
	case 0x04:
	case 0x05:
	case 0x06:
	case 7:
	{
		 lugar++;
	}
	break;
	default:
	{
		 lugar = 25;
	}
	break;
	}

Don't rely on the debugger to accurately reflect the flow of the code when optimized. The compiler can rearrange and simplify things as needed.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6
TDK
Guru

No doubt what is happening here is the compiler realizes cases 0 through 7 are the same, so it simplifies it to the following:

	switch(lugar)
	{
	case 0x01:
	case 0x02:
	case 0x03:
	case 0x04:
	case 0x05:
	case 0x06:
	case 7:
	{
		 lugar++;
	}
	break;
	default:
	{
		 lugar = 25;
	}
	break;
	}

Don't rely on the debugger to accurately reflect the flow of the code when optimized. The compiler can rearrange and simplify things as needed.

If you feel a post has answered your question, please click "Accept as Solution".

To understand the generated code look at a disassembly. See how it flows, and how it manages the functionality you expressed in its simplest form.

There is unlikely to be a linear one-to-one relationship between C lines and assembler lines when optimized.

You shouldn't need to single step C code to understand how it works.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

How does the optimized code behave differently than the non-optimized one?

Don't forget to use volatile for variables shared between interrupts and main.

JW

VRami.1
Associate III

Thanks @TDK for the help, this was exactly the problem, a C problem, I need to learn to think in optmimization mode to avoid this from happening again.

Thanks @Community member​ , I neet to learn to thin in optimization mode.

Yeap @Community member​ . I neet to learn to thin in optimization mode.