Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c99 inline semantics with gcc (mspgcc)

Tags:

c

extern

inline

I am writing a couple of functions that I would like to inline.

Reading here and using the second c99 inline option with inline on all declarations and definitions, like so:

extern inline void SPFD54124B_write_cmd(uint16_t command);

in a header, and

inline void SPFD54124B_write_cmd(uint16_t command)
{
    spi_write(command, CMD_WIDTH);
}

in a corresponding c file. I was expecting to get inlined versions of the functions.

But when I compile i get:

Generating dependencies dep/spi.d from src/spi.c
Generating dependencies dep/spfd54124b.d from src/spfd54124b.c
Generating dependencies dep/pomodoro.d from src/pomodoro.c
Generating dependencies dep/font8x8_ualnum.d from src/font8x8_ualnum.c
Generating dependencies dep/font8x8_basic.d from src/font8x8_basic.c
Generating dependencies dep/evading_util.d from src/evading_util.c
Compiling src/evading_util.c
Compiling src/font8x8_basic.c
Compiling src/font8x8_ualnum.c
Compiling src/pomodoro.c
src/spfd54124b.h:96:20: warning: inline function 'SPFD54124B_write_pixel' declared but never defined [enabled by default]
src/spfd54124b.h:95:20: warning: inline function 'SPFD54124B_write_param' declared but never defined [enabled by default]
src/spfd54124b.h:94:20: warning: inline function 'SPFD54124B_write_cmd' declared but never defined [enabled by default]
src/spi.h:22:20: warning: inline function 'spi_write' declared but never defined [enabled by default]
src/spfd54124b.h:96:20: warning: inline function 'SPFD54124B_write_pixel' declared but never defined [enabled by default]
src/spfd54124b.h:95:20: warning: inline function 'SPFD54124B_write_param' declared but never defined [enabled by default]
src/spfd54124b.h:94:20: warning: inline function 'SPFD54124B_write_cmd' declared but never defined [enabled by default]
src/spi.h:22:20: warning: inline function 'spi_write' declared but never defined [enabled by default]
src/pomodoro.c: In function 'main':
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:29:25: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:31:25: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:35:25: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:36:25: warning: called from here [-Winline]
src/spfd54124b.h:96:20: warning: inlining failed in call to 'SPFD54124B_write_pixel': function body not available [-Winline]
src/pomodoro.c:40:31: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:43:25: warning: called from here [-Winline]
Compiling src/spfd54124b.c
src/spi.h:22:20: warning: inline function 'spi_write' declared but never defined [enabled by default]
src/spi.h:22:20: warning: inline function 'spi_write' declared but never defined [enabled by default]
src/spfd54124b.c: In function 'SPFD54124B_init':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:124:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:124:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_read':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:25:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:29:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_write_cmd':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:124:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_write_param':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_write_pixel':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_setrow':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:124:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_setcol':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:124:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_lputch':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:124:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spfd54124b.c: In function 'SPFD54124B_putch':
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:124:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
src/spi.h:22:20: warning: inlining failed in call to 'spi_write': function body not available [-Winline]
src/spfd54124b.c:129:14: warning: called from here [-Winline]
Compiling src/spi.c
Linking bin/pomodoro.elf

>>>> Size of Firmware <<<<
   text    data     bss     dec     hex filename
   3150       0       2    3152     c50 bin/pomodoro.elf

src/spfd54124b.h:96:20: warning: inline function 'SPFD54124B_write_pixel' declared but never defined [enabled by default]
src/spfd54124b.h:95:20: warning: inline function 'SPFD54124B_write_param' declared but never defined [enabled by default]
src/spfd54124b.h:94:20: warning: inline function 'SPFD54124B_write_cmd' declared but never defined [enabled by default]
src/spi.h:22:20: warning: inline function 'spi_write' declared but never defined [enabled by default]
src/spfd54124b.h:96:20: warning: inline function 'SPFD54124B_write_pixel' declared but never defined [enabled by default]
src/spfd54124b.h:95:20: warning: inline function 'SPFD54124B_write_param' declared but never defined [enabled by default]
src/spfd54124b.h:94:20: warning: inline function 'SPFD54124B_write_cmd' declared but never defined [enabled by default]
src/spi.h:22:20: warning: inline function 'spi_write' declared but never defined [enabled by default]
src/pomodoro.c: In function 'main':
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:29:25: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:31:25: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:35:25: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:36:25: warning: called from here [-Winline]
src/spfd54124b.h:96:20: warning: inlining failed in call to 'SPFD54124B_write_pixel': function body not available [-Winline]
src/pomodoro.c:40:31: warning: called from here [-Winline]
src/spfd54124b.h:94:20: warning: inlining failed in call to 'SPFD54124B_write_cmd': function body not available [-Winline]
src/pomodoro.c:43:25: warning: called from here [-Winline]

I'm not sure I understand the different inlining alternatives in c99.

like image 968
evading Avatar asked Jun 23 '13 22:06

evading


People also ask

Does GCC automatically inline functions?

GCC automatically inlines member functions defined within the class body of C++ programs even if they are not explicitly declared inline . (You can override this with -fno-default-inline ; see Options Controlling C++ Dialect.)

Can inline functions extern?

Similarly, if you define a function as extern inline , or redeclare an inline function as extern , the function simply becomes a regular, external function and is not inlined. End of C only. Beginning of C++ only.

What is inline C?

Inline Function are those function whose definitions are small and be substituted at the place where its function call is happened. Function substitution is totally compiler choice. Let's take below example: #include <stdio.h> // Inline function in C.


2 Answers

You have things exactly the wrong way around from the way you need them. In the header, you should use:

inline void SPFD54124B_write_cmd(uint16_t command)
{
    spi_write(command, CMD_WIDTH);
}

In the translation units that include this header, this will create an inline function with external linkage. In exactly one of these translation units you should also place the declaration:

extern void SPFD54124B_write_cmd(uint16_t);

This (together with the inline definition from the header) will create an external definition of the function. The other files that include the header but do not include the extern declaration will create an inline definition of the function: a definition only available in that translation unit, but that does not forbid an external definition elsewhere.

In total you will have one external definition of the function, and each file that includes the header will also have a non-external definition available; the compiler can use either. Conceptually there is still just one function called SPFD54124B_write_cmd in the complete program - for example if you take the address of the function in multiple translation units you should get the same value.

As an alternative, you can put this in the header:

static inline void SPFD54124B_write_cmd(uint16_t command)
{
    spi_write(command, CMD_WIDTH);
}

and use no extern declaration at all; this will create an inline function with internal linkage in each file that includes the header. There will be no external definition of the function at all, and conceptually each translation unit that includes the header has its own independent copy of the function.


(It should be noted for posterity that GCC's current default mode is "gnu89", which does not implement C99 semantics for inline)

like image 115
caf Avatar answered Sep 30 '22 00:09

caf


To ensure that a function ACTUALLY can be inlined, it pretty much has to be defined in the header-file.

When you don't do that, most compilers won't actually inline the function.

So my suggestion would be to move the actual function content into the header file:

inline void SPFD54124B_write_cmd(uint16_t command)
{
    spi_write(command, CMD_WIDTH);
}
like image 42
Mats Petersson Avatar answered Sep 30 '22 01:09

Mats Petersson