Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Inline functions have addresses?

Reply
Thread Tools

Inline functions have addresses?

 
 
SG
Guest
Posts: n/a
 
      07-27-2010
On 27 Jul., 09:19, Juha Nieminen <nos...@thanks.invalid> wrote:
> SG <s.gesem...@gmail.com> wrote:
> > In C the inline keyword is just a decoration. As far as I can tell, it
> > doesn't have any effect on the semantics of your program (unlike in C+
> > +). To avoid multiple definition errors C programmers often use inline
> > in combination with static which makes the function to have internal
> > linkage.

>
> * Does that mean it's not possible in C to do this (and have it work in
> the same way)?
>
> * * inline void foo()
> * * {
> * * * * static int counter = 0;
> * * * * ++counter;
> * * * * ...
> * * }


As far as I know, in C, inline functions with _external_linkage_ are
subject to some restrictions. One of these restrictions is that they
are not allowed to have static variables. So, your example is not
valid C99.
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      07-27-2010
On Jul 27, 8:19 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> SG <s.gesem...@gmail.com> wrote:
> > In C the inline keyword is just a decoration. As far as I can tell, it
> > doesn't have any effect on the semantics of your program (unlike in C+
> > +). To avoid multiple definition errors C programmers often use inline
> > in combination with static which makes the function to have internal
> > linkage.


> Does that mean it's not possible in C to do this (and have it work in
> the same way)?


> inline void foo()
> {
> static int counter = 0;
> ++counter;
> ...
> }


IIRC (and this is just from memory---I don't have my copy of the
C standard around to check), the above is undefined behavior in
C (but not in C++, where the compiler is required to make it
work).

--
James Kanze
 
Reply With Quote
 
 
 
 
Juha Nieminen
Guest
Posts: n/a
 
      07-27-2010
James Kanze <> wrote:
>> Does that mean it's not possible in C to do this (and have it work in
>> the same way)?

>
>> inline void foo()
>> {
>> static int counter = 0;
>> ++counter;
>> ...
>> }

>
> IIRC (and this is just from memory---I don't have my copy of the
> C standard around to check), the above is undefined behavior in
> C (but not in C++, where the compiler is required to make it
> work).


Is there a good reason for this?
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      07-28-2010
On 27 Jul., 19:48, Juha Nieminen <nos...@thanks.invalid> wrote:
> James Kanze <james.ka...@gmail.com> wrote:
> >> * Does that mean it's not possible in C to do this (and have it work in
> >> the same way)?

>
> >> * * inline void foo()
> >> * * {
> >> * * * * static int counter = 0;
> >> * * * * ++counter;
> >> * * * * ...
> >> * * }

>
> > IIRC (and this is just from memory---I don't have my copy of the
> > C standard around to check), the above is undefined behavior in
> > C (but not in C++, where the compiler is required to make it
> > work).

>
> * Is there a good reason for this?


From http://www.open-std.org/JTC1/SC22/WG...docs/n1256.pdf
(draft of C99+TC1+TC2+TC3 from 2007)

6.7.4/3:
"An inline definition of a function with external linkage shall not
contain a definition of a modifiable object with static storage
duration, and shall not contain a reference to an identifier with
internal linkage."

6.7.4/6:
"[...] For a function with external linkage, the following
restrictions apply: If a function is declared with an inline
function specifier, then it shall also be defined in the same
translation unit. If all of the file scope declarations for a
function in a translation unit include the inline function
specifier without extern, then the definition in that
translation unit is an inline definition. An inline definition
does not provide an external definition for the function, and does
not forbid an external definition in another translation unit.
An inline definition provides an alternative to an external
definition, which a translator may use to implement any call to
the function in the same translation unit. It is unspecified
whether a call to the function uses the inline definition or the
external definition."

If I understand this correctly, inline in C is more restrictive than
in C++ (w.r.t. static variables for example) and you have to (or
should) provide an "external definition" of an inline function with
external linkage in exactly one translation unit like this:

----------8<----------

// foo.h
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED

inline int add(int a, int b) {return a+b;}

#endif

----------8<----------

// foo.c
#include "foo.h"

// This declaration makes the definition from the
// header an "external definition" in *this* TU.
extern inline int add(int,int);

----------8<----------

Did I get this right?

Cheers!
SG
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      07-28-2010
On 28 Jul., 10:55, SG wrote:
> ----------8<----------
>
> * // foo.h
> * #ifndef FOO_H_INCLUDED
> * #define FOO_H_INCLUDED
>
> * inline int add(int a, int b) {return a+b;}
>
> * #endif
>
> ----------8<----------
>
> * // foo.c
> * #include "foo.h"
>
> * // This declaration makes the definition from the
> * // header an "external definition" in *this* TU.
> * extern inline int add(int,int);
>
> ----------8<----------
>
> Did I get this right?


It seems so. But using the header in another file and compiling
+linking it with GCC like this:

> gcc -o test test.c foo.c


leads to the following error:

test.c: multiple definition of 'add'
foo.c: first definition here

Now, if I add the option "-std=c99" this goes away and it compiles
+links just fine. It seems that GCC in its default mode doesn't
respect the C99 rules regarding inline. It doesn't seem to distinguish
between "inline definition" and "extern definition" and always
generates a symbol for the function (which explains the linker error)
*unless* you specifically enable the C99 mode.

Ok, so, in C99 you don't *have* to use inline in combination with
static and inline is not just a "decoration" but comes with its own
set of rules. I stand corrected.

Cheers!
SG
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-28-2010
On Jul 27, 6:48 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> James Kanze <james.ka...@gmail.com> wrote:
> >> Does that mean it's not possible in C to do this (and have it work in
> >> the same way)?


> >> inline void foo()
> >> {
> >> static int counter = 0;
> >> ++counter;
> >> ...
> >> }


> > IIRC (and this is just from memory---I don't have my copy of the
> > C standard around to check), the above is undefined behavior in
> > C (but not in C++, where the compiler is required to make it
> > work).


> Is there a good reason for this?


Make things easier for the compiler writer.

Making a local static work in an inline function with external
linkage requires some special handling. The same special
handling is needed for templates in C++, so making them work in
C++ is basically free. In C, the compiler would have to add
this special handling, just for static local variables in inline
functions.

--
James Kanze
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      07-28-2010
James Kanze <> wrote:
>> Is there a good reason for this?

>
> Make things easier for the compiler writer.


I have always had the opinion that programs (in this particular case
compilers) should make the user's life simpler, not the other way around
(iow. restricting the user from using a logical feature which the language
could obviously support because such a restriction makes writing a compiler
easier is going in the wrong direction in the who-is-helping-who line).

(This is the same reason why I strongly oppose eg. MathML, compared to
something like LaTeX equations. MathML exists to make it easier for
programmers to write programs which parse mathematical expressions, at
the cost of greatly complexifying the work of the user, who needs to
write the mathematical expression in MathML. LaTeX goes the other way
around: It makes it as easy as possible for the user to write mathematical
expressions, at the cost of greatly complexifying the program that parses
the expression. This is the correct direction. Programs are there to help
users, not the other way around.)
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-29-2010
On Jul 28, 6:06 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> James Kanze <james.ka...@gmail.com> wrote:
> >> Is there a good reason for this?


> > Make things easier for the compiler writer.


> I have always had the opinion that programs (in this particular case
> compilers) should make the user's life simpler, not the other way around
> (iow. restricting the user from using a logical feature which the language
> could obviously support because such a restriction makes writing a compiler
> easier is going in the wrong direction in the who-is-helping-who line).


I tend to agree. In the case of C: historically, C was first
designed for very small systems, and implemented by very small
teams (two or three people). If you didn't make the compiler
simpler for for the compiler writer, you didn't get a compiler.
Today, this still influences the "taste" of C.

With regards to inline functions, I sort of agree with the
C committee. The mechanism is rather heavy, and requiring it
uniquely for inline functions does seem a bit overdoing things.
(But then, given the size and performance of modern hardware,
I don't see the point of C anyway. Anything C can do, C++ can
do better.)

--
James Kanze
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      07-29-2010
James Kanze <> wrote:
> With regards to inline functions, I sort of agree with the
> C committee. The mechanism is rather heavy, and requiring it
> uniquely for inline functions does seem a bit overdoing things.


Strictly speaking, isn't it something that complicates the *linker*
rather than the compiler itself (other than the compiler having to
generate instructions for the linker to merge the static variables
into one)?
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      07-29-2010
On 29 Jul., 14:27, Juha Nieminen wrote:
> James Kanze <james.ka...@gmail.com> wrote:
> > With regards to inline functions, I sort of agree with the
> > C committee. *The mechanism is rather heavy, and requiring it
> > uniquely for inline functions does seem a bit overdoing things.

>
> * Strictly speaking, isn't it something that complicates the *linker*
> rather than the compiler itself (other than the compiler having to
> generate instructions for the linker to merge the static variables
> into one)?


Yes, I think that's exactly the case. The rules of C99 inline seem to
easily support "simple linkers" whereas a straight forward C++
implementation would use a linker that simply "merges" certain
multiple definitions (inline functions, function templates, static
members of class templates) and complains about others (non-inline non-
template functions, other static objects). Apparently, the GCC C++
compiler marks some symbols as "weak" to tell the linker to ignore
multiple definitions. Of course, your object file format has to
support this as well. I've already seen an embedded "C linker" choke
on compiled C++ code. It wasn't able to cope with an inline function.

Cheers!
SG
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Multiple functions (one version being inline and other beingnon-inline) Rahul C++ 3 02-28-2008 03:28 PM
converting inline functions to C functions jamihuq C Programming 7 05-17-2006 08:46 AM
Tool which expands implicitly inline inline functions tthunder@gmx.de C++ 3 06-16-2005 12:54 AM
Can we have inline functions in c? Prafull Soni C Programming 15 03-07-2005 10:46 PM
External inline functions calling internal inline functions Daniel Vallstrom C Programming 2 11-21-2003 01:57 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57