Inline functions and warning

P

pozz

I'm creating a small library (mylib.c and mylib.h) and I want the
compiler expands
some functions (foo1() and foo2()) inline, both inside mylib.c and in
a second module
(main.c).

My compiler allows inline expansion with #pragma.

-- mylib.h --
#pragma inline foo1, foo2
void foo1(void)
{
...
}
void foo2(void)
{
...
}
--

-- mylibc.c --
#include "mylib.h"
void foo(void)
{
...
foo1();
...
foo2();
...
}
--

-- main.c --
#include "mylib.h"
int main(int argc, char *argv[])
{
...
foo1();
...
foo2();
...
}
--

The linking process gives two warnings, one for each function:
duplicate symbol definition.
Indeed foo1() and foo2() functions are correctly expanded inline (both
in main.c and mylib.c),
but they are expanded as a function per se in both files.
Of course the linker notes two definition of the same symbols.

I tried to declare static foo1() and foo2() in mylib.h, and it works
great. The compilation and
linking processes work great. However in this case I have another
problem. If in a third module
(module.c) I include mylib.h, but I don't use inline functions (foo1()
and/or foo2()) the compiler
gives another warning: static symbol defined but not used.

Any suggestions?
 
N

Nick Keighley

I'm creating a small library (mylib.c and mylib.h) and I want the
compiler expands
some functions (foo1() and foo2()) inline, both inside mylib.c and in
a second module
(main.c).

My compiler allows inline expansion with #pragma.

this is non-standard. The latest standard for C (C99) supports an
"inline" keyword
-- mylib.h --
#pragma inline foo1, foo2
void foo1(void)
{
  ...}

-- mylibc.c --
#include "mylib.h"
void foo(void)
{
  ...
  foo1();
  ...
  foo2();
  ...}

--

-- main.c --
#include "mylib.h"
int main(int argc, char *argv[])
{
  ...
  foo1();
  ...
  foo2();
  ...}

--

The linking process gives two warnings, one for each function:
duplicate symbol definition.
Indeed foo1() and foo2() functions are correctly expanded inline (both
in main.c and mylib.c),
but they are expanded as a function per se in both files.
Of course the linker notes two definition of the same symbols.

I tried to declare static foo1() and foo2() in mylib.h, and it works
great. The compilation and
linking processes work great. However in this case I have another
problem. If in a third module
(module.c) I include mylib.h, but I don't use inline functions (foo1()
and/or foo2()) the compiler
gives another warning: static symbol defined but not used.

Any suggestions?

ignore the warning? Could you move the inline functions to another
header? One you only include when you need it.
 
F

Francois Grieu

I'm creating a small library (mylib.c and mylib.h) and I want the
compiler expands
some functions (foo1() and foo2()) inline, both inside mylib.c and in
a second module
(main.c).

My compiler allows inline expansion with #pragma.

-- mylib.h --
#pragma inline foo1, foo2
void foo1(void)
{
...
}
void foo2(void)
{
...
}
--

-- mylibc.c --
#include "mylib.h"
void foo(void)
{
...
foo1();
...
foo2();
...
}
--

-- main.c --
#include "mylib.h"
int main(int argc, char *argv[])
{
...
foo1();
...
foo2();
...
}
--

The linking process gives two warnings, one for each function:
duplicate symbol definition.
Indeed foo1() and foo2() functions are correctly expanded inline (both
in main.c and mylib.c),
but they are expanded as a function per se in both files.
Of course the linker notes two definition of the same symbols.

I tried to declare static foo1() and foo2() in mylib.h, and it works
great. The compilation and
linking processes work great. However in this case I have another
problem. If in a third module
(module.c) I include mylib.h, but I don't use inline functions (foo1()
and/or foo2()) the compiler
gives another warning: static symbol defined but not used.

Any suggestions?

Warnings are not error for good reasons, including that once
understood, it is at least conceivable to ignore them.

If your question is system specific, please tell us the system
(or ask it in the appropriate group)

For portability, rewrite foo1 and foo2 as a macro (if they are
short enough).

On systems with C99-conformant inline, the right syntax is

-- mylib.h --
inline void foo1(void)
{
(..)
}
inline void foo2(void)
{
(..)
}

For some Microsoft compilers operating in C mode, add
#define inline __inline
at the beginning of mylib.h

Francois Grieu
 
P

pozz

this is non-standard. The latest standard for C (C99) supports an
"inline" keyword

Oh yes, I know it, but unfortunately my compiler isn't C99 compliant.
It's an old compiler for a 16-bit microcontroller.

ignore the warning? Could you move the inline functions to another
header? One you only include when you need it.

You understand, they aren't elegant solutions :-(
 
P

pozz

Warnings are not error for good reasons, including that once
understood, it is at least conceivable to ignore them.

If your question is system specific, please tell us the system
(or ask it in the appropriate group)

It's an old compiler for a 16-bit microcontroller.

For portability, rewrite foo1 and foo2 as a macro (if they are
short enough).

Oh I know, but in that case I couldn't call the macro in a way
similar to the following:
int c = 1;
foo1(c++);
Indeed macro/function foo1() use the parameter many times.
 
S

Stephen Sprunk

Oh I know, but in that case I couldn't call the macro in a way
similar to the following:
int c = 1;
foo1(c++);
Indeed macro/function foo1() use the parameter many times.

.... and one of the reasons function-like macros are conventionally
written in upper case is to remind programmers not to call them that way.

Back to your original question: any function defined in a header needs
to be declared as static to avoid the multiple-definition problem you've
run into if/when it is #included into multiple source files. If your
compiler complains about unused static functions, hopefully there is a
switch to disable that; if not, either ignore it or play games with the
pre-processor like this:

// funcs.h
#ifdef NEED_FOO
static T foo(...) {
....
}
#endif
#ifdef NEED_BAR
static T bar(...) {
....
}
#endif

// x.c
#define NEED_FOO
#include <funcs.h>
....

// y.c
#define NEED_BAR
#include <funcs.h>
....

It's ugly, but it'll solve your problem.

S
 
F

Francois Grieu

Oh I know, but in that case I couldn't call the macro in a way
similar to the following:
int c = 1;
foo1(c++);
Indeed macro/function foo1() use the parameter many times.

Sometime you can workaround this issue with a macro

// macro foo1 accepting an integer parameter that can be an
//expression with side effect
#define FOO1(input) do{\
int x = (input);\
OUTPORT = (x&(x-1))^x; /* massage x */\
}while(0)

For many compilers, including ancient compilers for 8-bit
CPUs that I use routinely, this generates good code.
It has limitations:

- macros using this technique can't simulate inline functions
that return results (at least portably; GCC has an extension
that allows a macro to return a result); instead, results
must be returned by passing a pointer, which in all my old
compilers is wasteful; or as a global, which in addition is
ugly.

- the maximum length of macros might be a portability issue.

- making readable such macros is hard, and conflicts with the
previous issue.

Francois Grieu
 
E

Eric Sosman

Oh yes, I know it, but unfortunately my compiler isn't C99 compliant.
It's an old compiler for a 16-bit microcontroller.

Then you really need to seek your answer from the compiler's own
documentation, not from the C language as such. Anything done with a
#pragma (other than a few C99-isms) is entirely compiler-specific, and
"extra-linguistic" from C's perspective. That is, we can tell you and
tell you and tell you about C99's `inline' keyword and the rules that
go along with it, but what we say may have little or nothing to do with
your compiler's #pragma. Sorry -- but that's the inevitable outcome
of using compiler-specific extensions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top