6.7.4 Function Specifiers
New C99 function: the inline adapted from C ++ is a function specifier that can only be used in function declarations. This is useful for optimizing programs that require the definition of a function that should be visible at the call site. (Note that the standard does not attempt to indicate the nature of these optimizations.)
Visibility is guaranteed if the function has an internal connection, or if it has an external connection and the call is in the same translation unit as the external definition. In these cases, the presence of an inline keyword in the declaration or the definition of a function has no effect, other than indicating that calls to this function should be optimized in preference to calls to other functions declared without the inline .
Visibility is a problem for calling a function with external communication, where the call is in different translation units from the function definition. In this case, the inline allows the translation unit containing the call to also contain a local or inline function definition.
A program may contain a translation block with an external definition, a translation block with a built-in definition, and a translation block with an announcement, but not a definition for a function. Calls in the latter translation system will use an external definition as usual.
An internal definition of a function is considered a different definition than an external definition. If a call to a func function with an external link occurs where the built-in definition is visible, the behavior is the same as if the call was made for another function, say __func , with an internal link. The corresponding program should not depend on what function is called. This is an embedded model in the standard.
An appropriate program should not rely on an implementation using an inline definition, nor can it rely on an implementation using an external definition. The address of the function is always the address corresponding to the external definition, but when this address is used to call the function, a built-in definition can be used. Therefore, the following example may not behave as expected.
inline const char *saddr(void) { static const char name[] = "saddr"; return name; } int compare_name(void) { return saddr() == saddr();
Since the implementation can use the built-in definition for one of the saddr calls and use the external definition for the other, the equality operation is not guaranteed to evaluate to 1 (true). This shows that static objects defined inside the built-in definition are different from the corresponding object in the external definition. This motivated the restriction by defining a const object of this type.
Invalidation was added to the Standard in such a way that it can be implemented using the existing linker technology, and the C99 embedding subset is compatible with C ++. This was achieved by requiring that exactly one translation unit containing a definition of an inline function, specified as one that provides an external definition of the function. Because of this, the specification simply consists of an declaration that either does not have the inline or contains both inline and extern , it will also be accepted by the C ++ translator.
Embedding in C99 extends the C ++ specification in two ways. First, if an inline function is declared in one translation unit, it does not need to be declared inline in every other translation unit. This allows, for example, a library function, which must be built into the library, but is only accessible through an external definition elsewhere. An alternative to using a wrapper function for an external function requires an additional name; and this can also adversely affect performance if the translator does not actually perform the built-in lookup.
Secondly, the requirement that all definitions of the built-in function be "exactly the same" is replaced by the requirement that the behavior of the program does not depend on whether the call is implemented with a visible built-in definition or an external definition of the function. This allows the built-in definition to be specialized for its use in a specific translation unit. For example, an external definition of a library function may include some argument checking that is not needed for calls made from other functions in the same library. These extensions have some advantages; and programmers who are concerned about compatibility might just abide by the stricter C ++ rules.
Note that built-in standard definitions of library functions in standard headers are not suitable for implementations, because this can break some inherited code that overrides standard library functions after including their headers. The inline intended only to provide users with a portable way to offer feature embedding. Since standard headers should not be portable, implementations have other options in accordance with:
#define abs(x) __builtin_abs(x)
or other non-portable mechanisms for embedding standard library functions.