This is the mail archive of the egcs@egcs.cygnus.com mailing list for the EGCS project. See the EGCS home page for more information.


[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

Re: kernel-2.2.1-undefined references.



In article <Pine.LNX.3.95.990208183457.433I-100000@penguin.transmeta.com> you write:

>In particular, "extern inline" has basically been documented to be a macro
>(some Clintonesque arguments to the contrary notwithstanding), and does
>not make sense to not inline - the documentation even says so. If I have
>to add an "extern" to force the inline, that's fine.

I'm sorry but this is bullshit. Read the fucking manual. I even took the time
to research gcc 2.7.2' extend.texi. Is that old enough for you ?
I have included the whole node of the documentation *here* so that you can't
accuse me of trying to finnagle my way out of a tight place...

------------------------
| @section An Inline Function is As Fast As a Macro
| @cindex inline functions
| @cindex integrating function code
| @cindex open coding
| @cindex macros, inline alternative
| 
| By declaring a function @code{inline}, you can direct GNU CC to
| integrate that function's code into the code for its callers.  This
| makes execution faster by eliminating the function-call overhead; in
| addition, if any of the actual argument values are constant, their known
| values may permit simplifications at compile time so that not all of the
| inline function's code needs to be included.  The effect on code size is
| less predictable; object code may be larger or smaller with function
| inlining, depending on the particular case.  Inlining of functions is an
| optimization and it really ``works'' only in optimizing compilation.  If
| you don't use @samp{-O}, no function is really inline.

First point, inlining is an optimization. As far as I know, optimizations
are fine-tuning, that should be termed as not changing semantics.

| To declare a function inline, use the @code{inline} keyword in its
| declaration, like this:
| 
| @example
| inline int
| inc (int *a)
| @{
|   (*a)++;
| @}
| @end example
| 
| (If you are writing a header file to be included in ANSI C programs, write
| @code{__inline__} instead of @code{inline}.  @xref{Alternate Keywords}.)

| You can also make all ``simple enough'' functions inline with the option
| @samp{-finline-functions}.  Note that certain usages in a function
| definition can make it unsuitable for inline substitution.

*WHAT* is not clear in the preceding paragraph ?  Stuff covered
by `certain usages in a function definition' is obviously very vague,
but the intent is not: inlining is an *optimization*. The compiler had better
do its damned best to implement it, but it has *no obligation* to inline
functions.

| Note that in C and Objective C, unlike C++, the @code{inline} keyword
| does not affect the linkage of the function.

| @cindex automatic @code{inline} for C++ member fns
| @cindex @code{inline} automatic for C++ member fns
| @cindex member fns, automatically @code{inline}
| @cindex C++ member fns, automatically @code{inline}
| GNU CC automatically inlines member functions defined within the class
| body of C++ programs even if they are not explicitly declared
| @code{inline}.  (You can override this with @samp{-fno-default-inline};
| @pxref{C++ Dialect Options,,Options Controlling C++ Dialect}.)

| @cindex inline functions, omission of
| When a function is both inline and @code{static}, if all calls to the
| function are integrated into the caller, and the function's address is
| never used, then the function's own assembler code is never referenced.
| In this case, GNU CC does not actually output assembler code for the
| function, unless you specify the option @samp{-fkeep-inline-functions}.
| Some calls cannot be integrated for various reasons (in particular,
| calls that precede the function's definition cannot be integrated, and
| neither can recursive calls within the definition).  If there is a
| nonintegrated call, then the function is compiled to assembler code as
| usual.  The function must also be compiled as usual if the program
| refers to its address, because that can't be inlined.
| 
| @cindex non-static inline function
| When an inline function is not @code{static}, then the compiler must assume
| that there may be calls from other source files; since a global symbol can
| be defined only once in any program, the function must not be defined in
| the other source files, so the calls therein cannot be integrated.
| Therefore, a non-@code{static} inline function is always compiled on its
| own in the usual fashion.
| 
| If you specify both @code{inline} and @code{extern} in the function
| definition, then the definition is used only for inlining.  In no case
| is the function compiled on its own, not even if you refer to its
| address explicitly.  Such an address becomes an external reference, as
| if you had only declared the function, and had not defined it.

| This combination of @code{inline} and @code{extern} has almost the
                                                          ^^^^^^
| effect of a macro.  The way to use it is to put a function definition in
| a header file with these keywords, and put another copy of the
| definition (lacking @code{inline} and @code{extern}) in a library file.
| The definition in the header file will cause most calls to the function
                                               ^^^^
| to be inlined.  If any uses of the function remain, they will refer to
| the single copy in the library.

I fail to see what's unclear about the preceding paragraph. The intent
is clear, code design is clear (why would you want to provide a library
definition for extern inline, except for the fact that not all calls are
guaranteed to be inlined).

| GNU C does not inline any functions when not optimizing.  It is not
| clear whether it is better to inline or not, in this case, but we found
| that a correct implementation when not optimizing was difficult.  So we
| did the easy thing, and turned it off.
| 

>Removing features without giving a reasonable way of doing the thing that
>gcc has successfully been doing for 8 years is not reasonable.

You can make a case for *changing* the documentation, you can say that 
egcs current is breaking your code, but the feature you're asking is
basically undocumented.  Heck, this old piece of evidence, which has not
changed thru gcc 2.8.1, and now egcs, contradicts your ranting.

>Codifying the fact that if you really _rely_ on inlines, do so with an
>"extern inline" is ok would be very reasonable. Maybe you could even say
>that "extern inline" is honoured even when not optimizing.

Documentation *explicitly* says otherwise. Documentation *explicitly* tells
you that you should not _rely_ on extern inline exclusively.

>> I prefer to follow the standard where it says that inline is a hint,
>> and only a hint.
>
>You also seem to prefer breaking documented behaviour.

Undocumented.

Now, don't get me wrong. I perfectly agree with you that it would be better
if egcs were able to inline the same functions (and more) than gcc used
to be able to. This is your way of asking that gets on my nerves.

Breaking compilers gratuitously is probably something the egcs folks are
not doing. They're trying hard to do a good job, and there are compromises
sometimes that need to be done.   The current documentation shows some
leeway for the compiler implementor. Changing slightly actually inlined 
functions does not contradict the documentation. Hell, it should not even
break code (apart from performance), or else, blech. There are some parts
of the Linux kernel I *don't* want to touch.

>You also seem to want to ignore the knowledgeable user that knows, for
>example, that yes, this is a frigging big inline, but it's only used in
>one place, and it's inline in order to make the code more readable, but I
>really want to have the compiler inline it for me to make the code faster. 

>Why not just say that for "extern inline" there are NO artifical limits,
>because the damn documentation _tells_ you that "extern inline" is a gcc
>extension to the language that creates a macro-like function. 

>Instead of breaking stuff that used to work. 

Well, telling it another way, you got bitten by non-portable code...