AnsweredAssumed Answered

GCC compiler bug? 2 variables share same address...

Question asked by Tyto _Negro_ on Jan 15, 2017
Latest reply on Jan 15, 2017 by waclawek.jan

I am working with a Nucleo L031K6 board and my application showed strange behaviour that I could finally track down as two C variables sharing the same memory location....

 

Not being a specialist in neither C nor the ST family, my question is: What am I doing wrong? or is this a bug in the compiler?

 

Below my stripped C source and the disassembly listing from the debugging session. Of course this application does not do anything at all anymore, but it still demonstrates the fault.

 

The variable "secs" shares his address with variable "txt[1][0]"

 

 

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l0xx_hal.h"

 int32_t tel;
 uint32_t Klokstat;
 uint8_t txt[1][5];
uint8_t secs;

/* Private function prototypes -----------------------------------------------*/
void Error_Handler(void);

int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
   HAL_Init();

    tel=0;
    secs = 58;
    Klokstat=33;
    txt[1][0]=67;

    while (1) {
    }
}  // END  MAIN

 


void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {
  }
  /* USER CODE END Error_Handler */
}

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
}
#endif


/******************************************************************************/
/*            Cortex-M0+ Processor Interruption and Exception Handlers         */
/******************************************************************************/
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

 


void TIM21_IRQHandler(void)
{

}

 

The disassembly listing shows that "secs" is stored at 0x2000 0451 and that the byte array "txt" starts at 0x2000 044c

Accessing txt[1][0] gives an offset of 5 and also accesses location 0x2000 0451 !

 


                     main:
08000239: 0x0000b500   push    {r7, lr}
0800023b: 0x0000af00   add     r7, sp, #0
 54                    HAL_Init();
0800023c: 0x00f0b8f8   bl      0x80003b0 <HAL_Init>
 57                      tel=0;
08000240: 0x0000064b   ldr     r3, [pc, #24]   ; (0x800025c <main+36>)
08000242: 0x00000022   movs    r2, #0
08000244: 0x00001a60   str     r2, [r3, #0]
 60                      secs = 58;
08000246: 0x0000064b   ldr     r3, [pc, #24]   ; (0x8000260 <main+40>)
08000248: 0x00003a22   movs    r2, #58 ; 0x3a
0800024a: 0x00001a70   strb    r2, [r3, #0]
 63                      Klokstat=33;
0800024c: 0x0000054b   ldr     r3, [pc, #20]   ; (0x8000264 <main+44>)
0800024e: 0x00002122   movs    r2, #33 ; 0x21
08000250: 0x00001a60   str     r2, [r3, #0]
 65                      txt[1][0]=67;
08000252: 0x0000054b   ldr     r3, [pc, #20]   ; (0x8000268 <main+48>)
08000254: 0x00004322   movs    r2, #67 ; 0x43
08000256: 0x00005a71   strb    r2, [r3, #5]
 73                      } // end while(1)
08000258: 0x0000fee7   b.n     0x8000258 <main+32>
0800025a: 0x0000c046   nop     ; (mov r8, r8)
0800025c: 0x00005404   lsls    r4, r2, #17
0800025e: 0x00000020   movs    r0, #0
08000260: 0x00005104   lsls    r1, r2, #17
08000262: 0x00000020   movs    r0, #0
08000264: 0x00005804   lsls    r0, r3, #17
08000266: 0x00000020   movs    r0, #0
08000268: 0x00004c04   lsls    r4, r1, #17
0800026a: 0x00000020   movs    r0, #0

Outcomes