This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

__forceinline causing Error L6218E?

Using Keil MCBSTM32 (STM32F103RB processor) and uVision3 V3.55a

The goal is to "encapsulate" data in C. To do this I want to create access methods (get/put) that are accessible externally, but the data, being declared static, is not.

I also want to appease those who want faster code so I was attempting to "inline" the methods.

The test code is as follows:

#include counter.h
static unsigned int counter;

/**
 Method to get counter.
*/
__forceinline unsigned int get_counter()
{
        return counter;
}

/**
 Method to set counter.
*/
__forceinline void put_counter( unsigned int val)
{
        counter = val;
}

The counter.h contains the following:

__forceinline unsigned int get_counter(void);
__forceinline void put_counter( unsigned int val);


(Note: tried the declarations in the .h file with and without the __forceinline)

The main() contains:

static unsigned int opt_test;

/*----------------------------------------------------------------------------
  MAIN function
 *----------------------------------------------------------------------------*/
int main (void) {


  stm32_Init ();                                  // STM32 setup

  GPIOB->ODR |=  (1 << (ledPos+8));               // switch on initial LED position

  while (1) {                                     // Loop forever

        opt_test = get_counter();
        opt_test++;
        put_counter( opt_test );

  } // end while


(Note: this was just tacked onto the "Timer" project to try things out)

What I get:

Build target 'MCBSTM32'
assembling STM32F10x.s...
creating preprocessor file for STM32_Init.c...
compiling STM32_Init.c...
creating preprocessor file for Timer.c...
compiling Timer.c...
creating preprocessor file for optimize.c...
compiling optimize.c...
linking...
.\Obj\Timer.axf: Error: L6218E: Undefined symbol get_counter (referred from timer.o).
.\Obj\Timer.axf: Error: L6218E: Undefined symbol put_counter (referred from timer.o).
Target not created

What I have tried: Compiled with optimization levels of 2 and 3.

Is this functionality actually working? If so, is there anything I should be looking out for that might cause this error?

Parents
  • You might have missed how inlining work.

    The compiler can not inline a function unless it sees the implementation of the function.

    So, to inline the code you need to place the function in the header file, and not in the c file. But that kind of breaks your goal to isolate the accesses...

    In your case - when you use the __forceinline attribute, then the compiler knows that the function will always be inlined. Because of this, the compiler need not create one copy of the file with external binding.

    When compiling the other c file, the compiler does not see the implementation of the function, so it must create code trying to access an externally linked function.

    In the end, the linker has one object file trying to access an external reference but no object file that exports such a function.

Reply
  • You might have missed how inlining work.

    The compiler can not inline a function unless it sees the implementation of the function.

    So, to inline the code you need to place the function in the header file, and not in the c file. But that kind of breaks your goal to isolate the accesses...

    In your case - when you use the __forceinline attribute, then the compiler knows that the function will always be inlined. Because of this, the compiler need not create one copy of the file with external binding.

    When compiling the other c file, the compiler does not see the implementation of the function, so it must create code trying to access an externally linked function.

    In the end, the linker has one object file trying to access an external reference but no object file that exports such a function.

Children