I am confused about inline
in C99.
Here is what I want:
- I want my function get inlined everywhere, not just limited in one translation unit (or one compilation unit, a
.c
file). - I want the address of the function consistent. If I save the address of the function in a function pointer, I want the function callable from the pointer, and I don't want duplication of the same function in different translation units (basically, I mean no
static inline
).
C++ inline
does exactly this.
But (and please correct me if I am wrong) in C99 there is no way to get this behavior.
I could have use static inline
, but it leads to duplication (the address of the same function in different translation unit is not the same). I don't want this duplication.
So, here are my questions:
- What is idea behind
inline
in C99? - What benefits does this design give over C++'s approach?
References:
- Here's a link that speaks highly of C99
inline
, but I don't understand why. Is this “only in exactly one compilation unit” restriction really that nice?
http://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/ - Here's the Rationale for C99
inline
. I've read it, but I don't understand it.
Is "inline" without "static" or "extern" ever useful in C99? - A nice post, provides strategies for using
inline
functions.
http://www.greenend.org.uk/rjk/tech/inline.html
Answers Summary
How to get C++ inline
behavior in C99 (Yes we can)
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
inline int my_max(int x, int y) {
return (x>y) ? (x) : (y);
}
void call_and_print_addr();
#endif
src.c
#include "head.h"
#include <stdio.h>
// This is necessary! And it should occurs and only occurs in one [.c] file
extern inline int my_max(int x, int y);
void call_and_print_addr() {
printf("%d %u\n", my_max(10, 100), (unsigned int)my_max);
}
main.c
#include <stdio.h>
#include "head.h"
int main() {
printf("%d %u\n", my_max(10, 100), (unsigned int)my_max);
call_and_print_addr();
return 0;
}
Compile it with: gcc -O3 main.c src.c -std=c99
Check the assembly with: gcc -O3 -S main.c src.c -std=c99
, You'll find that my_max
is inlined in both call_and_print_addr()
and main()
.
Actually, this is exactly the same instructions given by ref 1 and ref 3. And what's wrong with me?
I used a too old version of GCC (3.4.5) to experiment, it give me “multiple definition of my_max
” error message, and this is the real reason why I am so confused. Shame.
Difference between C99 and C++ inline
Actually you can compile the example above by g++
: g++ main.c src.c
extern inline int my_max(int x, int y);
is redundant in C++, but necessary in C99.
So what does it do in C99?
Again, use gcc -O3 -S main.c src.c -std=c99
, you'll find something like this in src.s
:
_my_max:
movl 4(%esp), %eax
movl 8(%esp), %edx
cmpl %eax, %edx
cmovge %edx, %eax
ret
.section .rdata,"dr"
If you cut extern inline int my_max(int x, int y);
and paste it into main.c
, you'll find these assembly code in main.s
.
So, by extern inline
, you tell the compiler where the true function my_max()
, which you can call it by its address, will be defined and compiled.
Now look back in C++, we can't specify it. We will never know where my_max()
will be, and this is the “vague linkage” by @Potatoswatter.
As is said by @Adriano, most of the time, we don't care about this detail, but C99 really removes the ambiguity.