Any preprocessor definition to tell if inline is supported?

M

Martin Wells

Is there anything like __inline_is_supported to indicate whether a
certain C compiler supports inline?

I'm writing my code as fully portable C89, but I want to use inline.

Martin
 
?

=?iso-2022-kr?q?Harald_van_D=0E=29=26=0Fk?=

Is there anything like __inline_is_supported to indicate whether a
certain C compiler supports inline?

I'm writing my code as fully portable C89, but I want to use inline.

No C89 compiler supports inline. They're not allowed to, since C89 allows
programmers to name their own objects and functions "inline". In other
words, this program is valid C89:

#include <stdio.h>
int main(int inline, char *argv[]) {
if (inline >= 2)
puts(argv[1]);
return 0;
}

Some compilers support something that looks like C89, but adds inline.
These are not C89 compilers. They refuse to compile valid programs such
as the above.

You can, however, remain portable by writing in the common subset of C89
and C99, and then you can use

#if __STDC_VERSION__ < 199901L
#define inline /* nothing */
#endif

static inline int zero(void) {
return 0;
}
 
M

Michal Nazarewicz

Martin Wells said:
Is there anything like __inline_is_supported to indicate whether a
certain C compiler supports inline?

I'm writing my code as fully portable C89, but I want to use inline.

I use the following myself:

#ifndef __GNUC__
# if __STDC_VERSION__ + 0 >= 199901L
# define __inline__ inline
# define __restrict__ restrict
# else
# define __inline__
# define __restrict__
# endif
#endif

__inline__ and __restrict__ identifiers are reserved though so it may
have some portability issues. __inline__ and __restrict__ keywords come
from GCC. It allows using them even if you are compiling your program
in C89 mode where there is no inline keyword.
 
M

Martin Wells

Harald:
No C89 compiler supports inline. They're not allowed to, since C89 allows
programmers to name their own objects and functions "inline". In other
words, this program is valid C89:

#include <stdio.h>
int main(int inline, char *argv[]) {
if (inline >= 2)
puts(argv[1]);
return 0;

}

Some compilers support something that looks like C89, but adds inline.
These are not C89 compilers. They refuse to compile valid programs such
as the above.


While these "C89 + extras compilers" may fail to compile the code you
show above, it's not inconceivable that a compliant C compiler could
work with the following:

inline int Func(void) { return 7; }

int main(void)
{
int inline = 6;

return 0;
}

There's already plenty of different C keywords that have different
meanings in different contexts. (Granted none of them can be used as
identifiers, but you get the picture).

You can, however, remain portable by writing in the common subset of C89
and C99, and then you can use

#if __STDC_VERSION__ < 199901L
#define inline /* nothing */
#endif

static inline int zero(void) {
return 0;


I'd be hesitant to use static, given that inline functions are, by
default, extern. Off the top of my head I can't think of any drawbacks
of making them static, but I know from past experience not to jump
into something just because I can't see the drawbacks off the top of
my head.

Can anyone see any drawbacks of making an inline function static?
(Except for being able to declare but not define it in another
translation unit).

And by the way, I do realise I could use further macro trickery to get
rid of the static.

Martin
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

I use the following myself:

#ifndef __GNUC__
# if __STDC_VERSION__ + 0 >= 199901L
# define __inline__ inline
# define __restrict__ restrict
# else
# define __inline__
# define __restrict__
# endif
#endif

__inline__ and __restrict__ identifiers are reserved though so it may
have some portability issues. __inline__ and __restrict__ keywords come
from GCC. It allows using them even if you are compiling your program
in C89 mode where there is no inline keyword.

You can go the other way around:

#if __STDC_VERSION__ >= 199901L
/*
* Uncomment this if you like:
#define inline inline
#define restrict restrict
*/
#elif defined(__GNUC__)
#define inline __inline__
#define restrict __restrict__
#elif defined(__Special_Other_Compiler__)
#define inline __inline
#define restrict /* nothing */
#else
#define inline /* nothing */
#define restrict /* nothing */
#endif

This, strictly speaking, still isn't valid C89, but it will work using
implementation extensions on GCC and SOC, and other C89 implementations
that don't define __GNUC__ or __Special_Other_Compiler__ must accept it
since you don't define any reserved identifiers this way. Additionally,
it is valid C99.

The reason it still isn't valid C89, is because an implementation is
allowed to define __GNUC__ without supporting any GNU extensions, and
similarly for SOC. Judging from what you're currently using, you don't
care about supporting such an implementation. I wouldn't either.

By the way, you don't need __STDC_VERSION__ + 0. Macros that are not
defined expand to 0 in #if expressions.
 
R

Richard Tobin

user923005 said:
For compilers that offer inline, many allow you to set a compiler
option to "inline any suitable function" which will not require any
decoration of the function name and will also probably guess better
than you will what to inline.

On the other hand, declaring your functions inline may cause them to
be inlined on compilers that other people use to compile your program,
and whose options you don't know.

-- Richard
 
U

user923005

Is there anything like __inline_is_supported to indicate whether a
certain C compiler supports inline?

I'm writing my code as fully portable C89, but I want to use inline.

Inline is just a compiler hint. The compiler is free to ignore you.

For compilers that offer inline, many allow you to set a compiler
option to "inline any suitable function" which will not require any
decoration of the function name and will also probably guess better
than you will what to inline.
 
?

=?iso-2022-kr?q?Harald_van_D=0E=29=26=0Fk?=

Harald:
No C89 compiler supports inline. They're not allowed to, since C89
allows programmers to name their own objects and functions "inline". In
other words, this program is valid C89:

#include <stdio.h>
int main(int inline, char *argv[]) {
if (inline >= 2)
puts(argv[1]);
return 0;

}

Some compilers support something that looks like C89, but adds inline.
These are not C89 compilers. They refuse to compile valid programs such
as the above.


While these "C89 + extras compilers" may fail to compile the code you
show above, it's not inconceivable that a compliant C compiler could
work with the following:

inline int Func(void) { return 7; }

int main(void)
{
int inline = 6;

return 0;
}

I'm not aware of any implementations that do this, but it's a fair point.
I don't believe there's any code that would break this way (although for
the other new keyword, restrict, there is).
There's already plenty of different C keywords that have different
meanings in different contexts. (Granted none of them can be used as
identifiers, but you get the picture).



I'd be hesitant to use static, given that inline functions are, by
default, extern.

Non-inline functions are always extern or static, but inline functions
are by default neither.
Off the top of my head I can't think of any drawbacks
of making them static, but I know from past experience not to jump into
something just because I can't see the drawbacks off the top of my head.

static inline int zero(void) { return 0; }
int foo(void) { return zero(); }

This calls the local zero function. It can be defined in as many units as
you like; since it's static, they won't conflict.

extern inline int zero(void) { return 0; }
int foo(void) { return zero(); }

This calls the local zero function. It can only be defined in this one
unit. If any other unit defines zero this way as well, it is an error.

inline int zero(void) { return 0; }
int foo(void) { return zero(); }

This calls either the local zero function, or some zero function defined
in another unit, depending on whether the compiler feels like inlining.
If no zero function is defined in another unit, it is an error, which may
go undetected.

(Note that this is what C99 gives you; it differs from certain C89
extensions to specify inlining.)
 
E

Eric Sosman

user923005 wrote On 09/24/07 17:27,:
Inline is just a compiler hint. The compiler is free to ignore you.

For compilers that offer inline, many allow you to set a compiler
option to "inline any suitable function" which will not require any
decoration of the function name and will also probably guess better
than you will what to inline.

"What he said." Also, be aware that the semantics
of `inline' in a C89-with-extras compiler may not be
exactly those used by a C99 compiler. Just knowing that
Frobozz Magic C can be made to recognize `inline' as a
keyword doesn't mean you can be sure what it means.
 
R

Richard Bos

Martin Wells said:
Harald:
No C89 compiler supports inline. They're not allowed to, since C89 allows
programmers to name their own objects and functions "inline". In other
words, this program is valid C89:

#include <stdio.h>
int main(int inline, char *argv[]) {
if (inline >= 2)
puts(argv[1]);
return 0;

}
While these "C89 + extras compilers" may fail to compile the code you
show above, it's not inconceivable that a compliant C compiler could
work with the following:

inline int Func(void) { return 7; }

int main(void)
{
int inline = 6;

return 0;
}

Possibly, but that would still leave cases like

/* Input is on the 4th line of the card */
#define inline 4

inline int func(void); /* Oops... */

Richard
 

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

Forum statistics

Threads
473,767
Messages
2,569,573
Members
45,046
Latest member
Gavizuho

Latest Threads

Top