cancel
Showing results for 
Search instead for 
Did you mean: 

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

Tyto _Negro_
Associate
Posted on January 15, 2017 at 21:27

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 ------------------------------------------------------------------*/

&sharpinclude 'main.h'

&sharpinclude '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 */

}

&sharpifdef USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)

{

}

&sharpendif

/******************************************************************************/

/*            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, &sharp0

 54                    HAL_Init();

0800023c: 0x00f0b8f8   bl      0x80003b0 <HAL_Init>

 57                      tel=0;

08000240: 0x0000064b   ldr     r3, [pc, &sharp24]   ; (0x800025c <main+36>)

08000242: 0x00000022   movs    r2, &sharp0

08000244: 0x00001a60   str     r2, [r3, &sharp0]

 60                      secs = 58;

08000246: 0x0000064b   ldr     r3, [pc, &sharp24]   ; (0x8000260 <main+40>)

08000248: 0x00003a22   movs    r2, &sharp58 ; 0x3a

0800024a: 0x00001a70   strb    r2, [r3, &sharp0]

 63                      Klokstat=33;

0800024c: 0x0000054b   ldr     r3, [pc, &sharp20]   ; (0x8000264 <main+44>)

0800024e: 0x00002122   movs    r2, &sharp33 ; 0x21

08000250: 0x00001a60   str     r2, [r3, &sharp0]

 65                      txt[1][0]=67;

08000252: 0x0000054b   ldr     r3, [pc, &sharp20]   ; (0x8000268 <main+48>)

08000254: 0x00004322   movs    r2, &sharp67 ; 0x43

08000256: 0x00005a71   strb    r2, [r3, &sharp5]

 73                      } // end while(1)

08000258: 0x0000fee7   b.n     0x8000258 <main+32>

0800025a: 0x0000c046   nop     ; (mov r8, r8)

0800025c: 0x00005404   lsls    r4, r2, &sharp17

0800025e: 0x00000020   movs    r0, &sharp0

08000260: 0x00005104   lsls    r1, r2, &sharp17

08000262: 0x00000020   movs    r0, &sharp0

08000264: 0x00005804   lsls    r0, r3, &sharp17

08000266: 0x00000020   movs    r0, &sharp0

08000268: 0x00004c04   lsls    r4, r1, &sharp17

0800026a: 0x00000020   movs    r0, &sharp0

#nucleo #stm32l031 #compiler #variables #bug #gcc
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on January 15, 2017 at 21:32

Indexes in C are 0-based, so to have txt[1][0] you need to define uint8_t txt[2][5];

JW

View solution in original post

2 REPLIES 2
Posted on January 15, 2017 at 21:32

Indexes in C are 0-based, so to have txt[1][0] you need to define uint8_t txt[2][5];

JW

Posted on January 15, 2017 at 23:15

Aaargh, what a blunder .... thanks I was just thinking I could use 0 and 1 as index, knowing it is 0-based, but of course it specifies the size...