inline functions vs. macros

I

Ian Collins

Richard said:
Ian Collins said:

Richard Heathfield wrote:

[...]

When writing C99 code, it is for
the time being (and, the way, we're going, for the foreseeable future
too) reasonable to keep the code portable to C90, unless one is prepared
to forego the advantages thereof.

True, which brings us back to the old dilemma of pragmatism or
portability.


For me, portability is part of pragmatism.

And so, of course, is non-portability.
Can't argue with that :)

I guess there isn't any way of knowing, but it would be interesting to
know how much C code is truly portable. Probably a small fraction of
one percent.
 
R

Richard Heathfield

Ian Collins said:
Richard said:
Ian Collins said:
[...] the old dilemma of pragmatism or portability.


For me, portability is part of pragmatism.

And so, of course, is non-portability.
Can't argue with that :)

I guess there isn't any way of knowing, but it would be interesting to
know how much C code is truly portable. Probably a small fraction of
one percent.

It depends on what you mean, I guess. If we're talking about C *programs*,
the figure is probably quite low, because so many C programs need to take
advantage of platform-specific features. But if we're talking about C
*libraries*, then the figure is considerably higher.

As I have occasionally mentioned before in comp.lang.c, I've worked on quite
a few projects in which portability was considered an extremely high
priority, and yet platform-specific features were required as well. This
dilemma was solved by keeping all the platform-specific stuff carefully
isolated into its own modules, with all the portable stuff in /its/ own
modules. The example I like best was a Web browser for set-top boxes, which
was developed on Windows and Linux (developer's choice!). Of around 500,000
lines of code, only 5,000 (just 1%!) were non-portable. The browser only
took about a person-month to port to each new platform, because of this
careful isolation.

Those who "rubbish" portability because they think it means turning your
back on your program's access to platform-specific features have simply not
thought the issue through. Those who develop *only* for one platform are
less likely to be convinced by the argument for portability, of course - at
least until either their platform vanishes underneath them or their boss
suddenly says "in our next release, we have to support the YAP6000 - get to
it!", whereupon they sit at their desks wondering where they left their CV.
 
K

Keith Thompson

Ian Collins said:
I guess there isn't any way of knowing, but it would be interesting to
know how much C code is truly portable. Probably a small fraction of
one percent.

Probably a small fraction of C programs are truly portable. But a
large proportion of the *code* in a well-written program should be
portable, with the system-specific portions relatively isolated.
 
D

Duncan Muirhead

It is, until someone innocently writes

x = CUBE(y++);

and gets undefined behavior for their trouble.
<snip>
There can be harder to spot multiple side effects, as in
CUBE(g(x)), where g has side effects. On the other hand if f is
side effect free but the compiler doesn't know that (e.g. f is
in a precompiled library), CUBE(f(x)) would lead to needless
recomputation.
 
R

Richard Tobin

inline further asserts that taking the address of the function is
illegal
[/QUOTE]
That's incorrect. There's absolutely nothing illegal in taking the
address of an inline function.

The previous poster was probably thinking (correctly) that it's not
usefully possible to take the address of a function that has been
inlined. If you take the address of a function declared inline, the
compiler will have to produce an out-of-line version as well.

-- Richard
 
L

Laurent Deniau

Richard said:
That's incorrect. There's absolutely nothing illegal in taking the
address of an inline function.


The previous poster was probably thinking (correctly) that it's not
usefully possible to take the address of a function that has been
inlined. If you take the address of a function declared inline, the
compiler will have to produce an out-of-line version as well.[/QUOTE]

Only if it is qualified with static.

a+, ld.
 
B

Ben Pfaff

Richard Heathfield said:
Ian Collins said:

I'm not sure what he means by that, either.

#define add_m(a, b) ((a) + (b))
static inline add_f(int a, int b) { return a + b; }

add_m(3,4) is a constant expression.
add_f(3,4) is not a constant expression.
 
H

Hallvard B Furuseth

For the purposes of portability or long term viability/maintainability,
use of C99 is *not* a reasonable recommendation. You should use C
compilers that will have long term support, or otherwise write code to
the lowest common denominator (portable C/C++.)

And one should also take a bit extra care with features like inline,
which were implemented elsewhere and with different semantics before
they became standardized in C99. (At least gcc had them, but I assume
others as well.)

The semantics of extern vs. inline is almost opposite in gcc from the
standard: 'extern inline' is used for a definition which is only
inlined, never compiled on its own. The gcc doc recommends to use
'static inline' only, that's compatible with C99. For inlines in .h
files, if you want to be compatible with not-quite-C99-compilers (which
fits most compilers nowadays), I think you'd need a mess of '#if's used
to #define an Inline macro or something.
 
A

Andrey Tarasevich

Richard said:
...


The previous poster was probably thinking (correctly) that it's not
usefully possible to take the address of a function that has been
inlined. If you take the address of a function declared inline, the
compiler will have to produce an out-of-line version as well.
...

Strictly speaking, "has been inlined" is not a property of the function itself.
"Has been inlined" is something that can only be said about each particular
invocation of the function, each particular call. And, as one would expect, it
is applied to each particular call _independently_. One particular call can be
inlined, while the other one might be implemented by a regular call to the
out-of-line version (regardless of whether the address of this inline function
is taken anywhere in the program)

It is true that an attempt to take the addresss of an inline function will make
the compiler to generate the out-of-line body for the function. But I don't see
how this can impact the "usefulness" of the function.
 
R

Richard Tobin

The previous poster was probably thinking (correctly) that it's not
usefully possible to take the address of a function that has been
inlined. If you take the address of a function declared inline, the
compiler will have to produce an out-of-line version as well.
[/QUOTE]
Strictly speaking, "has been inlined" is not a property of the
function itself. "Has been inlined" is something that can only be
said about each particular invocation of the function, each
particular call.

Of course I meant "all of whose calls have been inlined".
It is true that an attempt to take the addresss of an inline function
will make the compiler to generate the out-of-line body for the
function. But I don't see how this can impact the "usefulness" of the
function.

I meant that you could conceivably get the address of the code
corresponding to an inlined call to the function, but that wouldn't be
useful.

-- Richard
 
K

Keith Thompson

I meant that you could conceivably get the address of the code
corresponding to an inlined call to the function, but that wouldn't be
useful.

No, you couldn't, unless you could use such an address to call the
function with arbitrary arguments.

You can legally take the address of a function (even if it's marked
"inline"), and you can use that address to call that function. That's
what function addresses are for.

Presumably a compiler could use "inline" as a hint that *direct* calls
to the function should be inlined. That doesn't make indirect calls
useless.

For example, I might have a function that computes some mathematical
formula. The formula might be simple enough that the overhead of a
normal function call is significant, so I mark it as "inline". But I
might still want to paas that function's address to, say, a function
that will compute an approximation of its integral over a specified
range. For that, I need its address.
 
R

Richard Tobin

I meant that you could conceivably get the address of the code
corresponding to an inlined call to the function, but that wouldn't be
useful.
[/QUOTE]
No, you couldn't, unless you could use such an address to call the
function with arbitrary arguments.

I'm clearly not being clear here. There's (probably) an address at
which the inlined code starts, but it would be useless for the
compiler to give you that as the address of the function, because you
couldn't use it to call the function. I didn't mean it would be
possible for a conforming C compiler to do such a thing.

I should just have left out "usefully" in my original comment:

The previous poster was probably thinking (correctly) that it's not
usefully possible to take the address of a function that has been
inlined.

I only put it in because I was expecting some pedant to say "it is
*possible* to take the address, you just can't call it".

-- Richard
 
K

Keith Thompson

No, you couldn't, unless you could use such an address to call the
function with arbitrary arguments.

I'm clearly not being clear here. There's (probably) an address at
which the inlined code starts, but it would be useless for the
compiler to give you that as the address of the function, because you
couldn't use it to call the function. I didn't mean it would be
possible for a conforming C compiler to do such a thing.

I should just have left out "usefully" in my original comment:

The previous poster was probably thinking (correctly) that it's not
usefully possible to take the address of a function that has been
inlined.

I only put it in because I was expecting some pedant to say "it is
*possible* to take the address, you just can't call it".[/QUOTE]

Ok, I see what you mean -- but I think you were mistaken in your
original assumption.

Here's what Paul Hsieh ("websnarf") wrote:
| Keep in mind that "static" function declarations are usually basically
| equivalent to what is intended by C99's "inline". For serious
| compilers, there should be no effective difference between the two
| (inline further asserts that taking the address of the function is
| illegal, however, a static function whose address *isn't* taken (which
| it can always determine because it *is* static) becomes equivalent in
| functional status.)

A couple of followups later, you wrote:
| The previous poster was probably thinking (correctly) that it's not
| usefully possible to take the address of a function that has been
| inlined. If you take the address of a function declared inline, the
| compiler will have to produce an out-of-line version as well.

I'm reasonably sure that Paul *meant* simply that the standard
disallows taking the address of a function to which "inline" has been
applied, just as it does for a variable to which 'register has been
applied. (He was mistaken, though the standard easily *could* have
imposed this restriction, and it arguably would have made some sense.)

Taking the address of an inlined expansion of a function doesn't make
much sense at all, though I suppose it would be theoretically
possible. By anticipating a point that nobody actually made, I'm
afraid you've managed (quite unintentionally, I'm certain) to create
the very confusion you were trying to prevent.
 

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

Similar Threads

Endianness macros 48
C Programming functions 2
inline functions 50
inline function vs function-like macro 2
Variadic debug macros 5
inline vs. function pointers 36
Generating functions with Macros in Perl 6
macros 2

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top