Inlines with external linkage

A

Andrey Tarasevich

JKop said:
Okay, I'm trying to get my head around this. Consider the following header
file, "yum.hpp":

#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
return k - 5;
}

#endif

Now, consider that this function is called... inlinedly... in every instance
that it's called throughout the entire program, like so:

A.cpp

#include "yum.hpp"

int blah(void)
{
return Yum('s');
}


B.cpp

#include "yum.hpp"

int poo(char* n)
{
return Yum(*n);
}

So there's no problem at all with that.
Excellent.

But consider that there's just 3 instances in the program where it's
called... outlinedly. Each of these three callings are from 3 different
source files, 3 different translation units. The "problem" here is that this
fully-fledged function will be in memory not once, twice, but thrice. 3
copies of it in memory - that's a waste. If I were to specify external
linkage (and how would I?) for this function, then the linker would start
complaining because I'd have a multiple definition for each of the
translation units that include my "yum.hpp".

Firstly, at the language level there's no way to detect how many copies
of fully-fledged function body you have in your code (until you start
comparing addresses of this functions in different translation units).
This means that implementation is allowed to keep several copies if it
decides to do so. I don't think it could be referred to as a "waste"
since you yourself declared this function as 'inline', i.e. you yourself
requested the compiler to substitute _a_ _copy_ of function code in
every place where it is called. If you think about it, this is pretty
much the same kind of "waste" as having several copies of fully-fledged
function body.

Secondly, in order to ensure that the function has the same address in
all translation units, the implementation should be able to recognize
the situations where the address of an inline function is taken and
"synchronize" their results between translation units, i.e. all pointers
to inline function should actually point to the same fully-fledged
function body. This is typically ensured by the linker. In the end, only
one copy of fully-fledged function body is really used in the program.
All other copies are not be used and can be safely discarded. This is
also done by the linker.

Thirdly, it is responsibility of the implementation to make sure that
there are no diagnostic messages (from the linker or anywhere else)
triggered by multiple copies of fully-fledged function body. There are
different ways to achieve that and I don't really understand why you
even care about it.
So here's my question: How to you get the function to be inline... yet...
where there's instances where it's called outlinedly, that there's only one
copy of it in memory, as opposed to 3.

In short, you follow these steps:

1. Generate three copies in memory (done by the compiler)
2. Make sure only one copy is actually used by redirecting all
references to a single copy (done by the linker)
3. Discard unused copies (done by the linker)
 
A

Alf P. Steinbach

* JKop:
Okay, I'm trying to get my head around this. Consider the following header
file, "yum.hpp":

#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
return k - 5;
}

#endif


Now, consider that this function is called... inlinedly... in every instance
that it's called throughout the entire program, like so:

A.cpp

#include "yum.hpp"

int blah(void)
{
return Yum('s');
}


B.cpp

#include "yum.hpp"

int poo(char* n)
{
return Yum(*n);
}


So there's no problem at all with that.

But consider that there's just 3 instances in the program where it's
called... outlinedly. Each of these three callings are from 3 different
source files, 3 different translation units. The "problem" here is that this
fully-fledged function will be in memory not once, twice, but thrice. 3
copies of it in memory - that's a waste.

Apart from the inlined calls a reasonable implementation will only have
one copy of the function in memory, since the function address is
required to be the same in all translation units.

If I were to specify external linkage (and how would I?)

By not using the word 'static'.

for this function, then the linker would start
complaining because I'd have a multiple definition for each of the
translation units that include my "yum.hpp".

No, that's exactly the what the word 'inline' _guarantees_ you won't
get (whether the function should additionally be inlined or not is up
to the compiler+linker, that aspect is not guaranteed in any way).


So here's my question: How to you get the function to be inline... yet...
where there's instances where it's called outlinedly, that there's only one
copy of it in memory, as opposed to 3.

No special action needed, that's what you get by default with any
reasonable implementation.
 
J

JKop

JKop posted:
#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
return k - 5;
}

#endif


Just to play devil's advocate here, I'm gonna rewrite that:


#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
static unsigned char counter = 3;


return ++counter - 5;
}

#endif


I want to make sure that ALL of the calls to this function, whether inline
or outline, all refer to the same static variable!


-JKop
 
A

Andrey Tarasevich

JKop said:
#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
static unsigned char counter = 3;


return ++counter - 5;
}

#endif


I want to make sure that ALL of the calls to this function, whether inline
or outline, all refer to the same static variable!
...

This simply means that the linker will have to merge all instances if
that 'counter' variable from different translation units into one. Just
like it merges all full-fledged bodies for the same inline function into
one (see my previous message).
 
B

Bob Hairgrove

JKop posted:



Just to play devil's advocate here, I'm gonna rewrite that:


#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
static unsigned char counter = 3;


return ++counter - 5;
}

#endif


I want to make sure that ALL of the calls to this function, whether inline
or outline, all refer to the same static variable!


-JKop

The inline directive does not *require* the compiler to actually copy
the function implementation anywhere, it is only a hint.

If the compiler "thinks" the function cannot (or should not) be
inlined, it won't do it.
 
J

JKop

Andrey Tarasevich posted:
This simply means that the linker will have to merge all instances if
that 'counter' variable from different translation units into one. Just
like it merges all full-fledged bodies for the same inline function
into one (see my previous message).


But I never asked it to do that.

I could just as easily want it to *not* do that.

As long as the inline function is in a header file, there will be multiple
instances of it for each seperate translation unit. That is, for each
translation unit into which it's included, there should be separate static
variables. That is, an inline function should be treated as if it is "static
inline". Inline functions have internal linkage - I believe someone-one
suggested that they don't.

It would be nice to just stick an inline function into a source file and
give it good old fashioned external linkage. One could argue that it can't
be expanded inlinedly into other translation units... but why can't the
compiler and linker collaborate and make it so?, ie.

Yum.cpp

inline int Yum(char k)
{
static unsigned char counter = 3;

return ++counter - 5;
}


and then

Crocodile.cpp

int main()
{
char j = 's';

Yum(j);
}


and still for it to be expanded inline in main() !


Does anyone disagree with me that "inline" == "static inline". If so, please
supply arguments.


I think it would be good if you could specify inline when you're *calling* a
function, even when the function's *defined* outline, and yet for it to
still use the same static variables - Consider a loop that loops
1,354,353,364,747,466,574 times. You'd want the functions called from within
it to be inlined, even if they are not defined with the "inline" keyword.
Out of that, I fantasize the following amendments to C++, specifically, the
addition of the following keywords:

For calling the function:

call_inline : calls the function inline, regardless of whether it's defined
with "inline"

call_outline : calls the function outline, regardless of whether it's
defined with "inline"

If you don't specify one of the above keywords, then you're implicitly
specifying the keyword:

call_according_to_definition : calls the function inline if it's defined
inline. Calls the function outline if it's not declared inline.


For defining the function:

inline : if the function is called with call_according_to_definition then
it's called inline.

outline : this will be an implicit keyword that's specified when you *don't*
define the function as inline. If the function is called with
call_according_to_definition, then it's called outline.

Here's a quick example:


double Cow(double pig)
{
return pig / 7 * 4 + 6 - 22 / 4;
}


int main()
{
unsigned long int amount_times = -1; //Max value (BTW, if have we come
to a decision yet on whether this is non-undefined behaviour?)

double r = 22.0;

for (unsigned long int counter = 0; counter < amount_times ; ++counter)
{
r = call_inline Cow(r); //Maybe some sort of angle brackets or
parenthesis or maybe even square brackets there
}
}


END OF FANTASY


-JKop
 
J

JKop

Bob Hairgrove posted:
The inline directive does not *require* the compiler to actually copy
the function implementation anywhere, it is only a hint.

If the compiler "thinks" the function cannot (or should not) be
inlined, it won't do it.


We've moved past that. We're talking about internal linkage Vs. external
linkage now. That is, for internal linkage, there'll be multiple instances
of the function and they'll all have *unique* static varibles; and for
external linkage, they'll be but one instance of the function and *all*
calls to it will work with the same static variables.


-JKop
 
A

Andre Kostur

JKop said:
JKop posted:



Just to play devil's advocate here, I'm gonna rewrite that:


#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
static unsigned char counter = 3;


return ++counter - 5;
}

#endif


I want to make sure that ALL of the calls to this function, whether
inline or outline, all refer to the same static variable!

Done. The Standard states that in section 7.1.2(4).
 
A

Andre Kostur

JKop said:
Here's a quick example:


double Cow(double pig)
{
return pig / 7 * 4 + 6 - 22 / 4;
}


int main()
{
unsigned long int amount_times = -1; //Max value (BTW, if
have we come
to a decision yet on whether this is non-undefined behaviour?)

double r = 22.0;

for (unsigned long int counter = 0; counter < amount_times ;
++counter) {
r = call_inline Cow(r); //Maybe some sort of angle
brackets or
parenthesis or maybe even square brackets there
}
}


END OF FANTASY

Simply declare Cow as inline, and let the optimizer deal with it. It's
generally smarter than you are about these things.
 
A

Andrey Tarasevich

JKop said:
But I never asked it to do that.

According to the language specification that's what is done _by_ _default_.
I could just as easily want it to *not* do that.

If you don't like it you have to specifically ask the implementation not
to do that. Place your inline function into header file but explicitly
declare it as 'static', for example. That way you'll get separate
'counter' in every translation unit.
As long as the inline function is in a header file, there will be multiple
instances of it for each seperate translation unit. That is, for each
translation unit into which it's included, there should be separate static
variables.

Conceptually - no. That would contradict the language specification.
Practically - that's exactly how it is at compilation stage. But later
the linker takes care of these separate variables merging them into one.
That is, an inline function should be treated as if it is "static
inline". Inline functions have internal linkage - I believe someone-one
suggested that they don't.

Inline functions have external linkage by default, just like non-inline
functions. If you want an inline function to have internal linkage, you
have to declare it as 'static'.
It would be nice to just stick an inline function into a source file and
give it good old fashioned external linkage. One could argue that it can't
be expanded inlinedly into other translation units... but why can't the
compiler and linker collaborate and make it so?, ie.

Yum.cpp

inline int Yum(char k)
{
static unsigned char counter = 3;

return ++counter - 5;
}


and then

Crocodile.cpp

int main()
{
char j = 's';

Yum(j);
}


and still for it to be expanded inline in main() !

Well, that probably didn't agree with the generally accepted idea of
what a "linker" is and what it can do. For this reason, the standard
decided to use different approach.
Does anyone disagree with me that "inline" == "static inline". If so, please
supply arguments.

According to the language standard, functions in C++ have external
linkage by default. The standard makes no exceptions from this rule for
inline functions.
 
J

JKop

Andre Kostur posted:
Simply declare Cow as inline, and let the optimizer deal with it. It's
generally smarter than you are about these things.

Consider that Cow is reusable code, maybe even within a library, so you
don't want to go messing with it.

-JKop
 
J

JKop

Andre Kostur posted:
Done. The Standard states that in section 7.1.2(4).


Here's something that's got me... concerned.


I wrote this little project:


Yum.hpp
-------

#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
static unsigned char counter = 3;


return ++counter - 5;
}

#endif



Yummy.hpp
---------

#ifndef INCLUDE_YUMMY_HPP
#define INCLUDE_YUMMY_HPP

inline int Yum(char k)
{
static unsigned char counter = 27;

counter *= 2;

return counter++ - 2;
}

#endif


ape.cpp
-------

#include "yummy.hpp"

unsigned int ape()
{
char rent = 'r';

Yum(rent);
}



cow.cpp
-------

extern int Yum(char); //Testing external linkage

unsigned int cow()
{
return Yum('p') - 23;
}



main.cpp
--------

#include <iostream>

#include "yum.hpp"

extern unsigned int cow();

extern unsigned int ape();


int main()
{
std::cout << Yum('r')
<< ape()
<< cow();

}

----

g++ -c main.cpp ape.cpp cow.cpp

g++ -o chello main.o ape.o cow.o

chello.exe outputs:

104294967272

----


A) cow.cpp compiles. Therefore there's a Yum function that has external
linkage. Which Yum is it calling? There's two different Yum functions. Two
different functions with the same name... Multiple Definition I would hope.
But NO!

C) The two inline functions both have external linkage, but they are
DIFFERENT. I'd like to get a multiple definition error, but I amn't. When a
certain translation unit calls the function Yum, which Yum is it calling?
AHH!



Seems like one big mess to me: Giving inline functions external linkage and
actually allowing multiple definitions is a recipe for disaster.


-JKop
 
J

JKop

Putting outputs in each function, I get:

Entered main
Entered Yum from Yum.hpp
-1
Entered ape
Entered Yum from Yum.hpp
0
Entered cow
Entered Yum from Yum.hpp
4294967274


For no particular reason, the Yum in Yummy.hpp is being ignored.


-JKop
 
A

Andre Kostur

JKop said:
Andre Kostur posted:



Here's something that's got me... concerned.


I wrote this little project:


Yum.hpp
-------

#ifndef INCLUDE_YUM_HPP
#define INCLUDE_YUM_HPP

inline int Yum(char k)
{
static unsigned char counter = 3;


return ++counter - 5;
}

#endif



Yummy.hpp
---------

#ifndef INCLUDE_YUMMY_HPP
#define INCLUDE_YUMMY_HPP

inline int Yum(char k)
{
static unsigned char counter = 27;

counter *= 2;

return counter++ - 2;
}

#endif


ape.cpp
-------

#include "yummy.hpp"

unsigned int ape()
{
char rent = 'r';

Yum(rent);
}



cow.cpp
-------

extern int Yum(char); //Testing external linkage

unsigned int cow()
{
return Yum('p') - 23;
}



main.cpp
--------

#include <iostream>

#include "yum.hpp"

extern unsigned int cow();

extern unsigned int ape();


int main()
{
std::cout << Yum('r')
<< ape()
<< cow();

}

----

g++ -c main.cpp ape.cpp cow.cpp

g++ -o chello main.o ape.o cow.o

chello.exe outputs:

104294967272

----


A) cow.cpp compiles. Therefore there's a Yum function that has
external linkage. Which Yum is it calling? There's two different Yum
functions. Two different functions with the same name... Multiple
Definition I would hope. But NO!

Not when Cow is compiled. There is only on amorphous Yum(char) function
floating around somewhere, to be resolved at link time.


Where's B) ? :)
C) The two inline functions both have external linkage, but they are
DIFFERENT. I'd like to get a multiple definition error, but I amn't.
When a certain translation unit calls the function Yum, which Yum is
it calling? AHH!

You're probably triggering a clause somewhere that when the linker sees
two instances of an inlined Yum(char) funtion, it's allowed to assume
that they're the same and can drop one of them. Remove the inline
qualifiers and see what happens.
Seems like one big mess to me: Giving inline functions external
linkage and actually allowing multiple definitions is a recipe for
disaster.

Seems like a mess that you've self-inflicted. First thing I'd do, is
forget using your "extern" statements, and use the appropriate header
files.
 
J

JKop

Andre Kostur posted:

Not when Cow is compiled. There is only on amorphous Yum(char) function
floating around somewhere, to be resolved at link time.

When Cow is compiled, no Yum exists AT ALL. All it has is an extern
statement.

At link time however, the translation unit formed from main.cpp will contain
an inline Yum function, just as the translation unit formed from ape.cpp
will contain and inline Yum function - two unique functions with external
linkage.

You're probably triggering a clause somewhere that when the linker sees
two instances of an inlined Yum(char) funtion, it's allowed to assume
that they're the same and can drop one of them. Remove the inline
qualifiers and see what happens.


I think this is bullshit. An inline function should be just like any other
function, ie. if it's defined twice, then the compiler doesn't flip a coin,
it spits out "RED ALERT! MULTIPLE DEFINITION!". The whole idea of namespaces
arose from this attitude.

From now on I'm sticking "static" in front of every inline function I write.
If two translation units call this function outline, or want an address to
it, I'll use global pointer variables.

Allowing multiple definitions is a farse.

Seems like a mess that you've self-inflicted. First thing I'd do, is
forget using your "extern" statements, and use the appropriate header
files.

I used the "extern" statements for clarity.

Which header files am I using that are inappropriate?


-JKop
 
A

Andrey Tarasevich

JKop said:
...
A) cow.cpp compiles. Therefore there's a Yum function that has external
linkage.

Wrong conclusion. The program is invalid, the behavior is undefined. It
can compile, but that means nothing. Moreover, it is possible to create
a conforming implementation that will not compile this program. The one
that you are using is simply too lazy to detect this type of error.
Which Yum is it calling? There's two different Yum functions. Two
different functions with the same name... Multiple Definition I would hope.
But NO!

The behavior is undefined. Maybe it is not calling any 'Yum's at all.
C) The two inline functions both have external linkage, but they are
DIFFERENT. I'd like to get a multiple definition error, but I amn't. When a
certain translation unit calls the function Yum, which Yum is it calling?
AHH!

One again, you have wrong idea about what "external linkage" is.
"External linkage" doesn't guarantee that function can be _called_ from
another translation unit. "External linkage" means that function can be
_referred_ from another translation units. What concrete ways of
"referring" are hiding behind this generic term depends on several other
factors. In your particular case "calling" function 'Yum' from 'cow.cpp'
is not a legal way to "refer" to it. The fact that program "compiles"
means nothing (I'm actually surprised that you use the "compilability"
of the program as some kind of proof of it validity.)
Seems like one big mess to me: Giving inline functions external linkage and
actually allowing multiple definitions is a recipe for disaster.

Trying to exploit the compiler's "security hole", which allows "linking"
to 'inline' functions from another translation unit, is a recipe for
disaster. Just don't do it.
 
J

JKop

Andrey Tarasevich posted:
Wrong conclusion. The program is invalid, the behavior is undefined.

I disagree.

Chapter and verse, please.
It can compile, but that means nothing. Moreover, it is possible to
create a conforming implementation that will not compile this program.
The one that you are using is simply too lazy to detect this type of
error.

Try to keep up here:

You have a translation unit. From within it, a function called "Yum" is
called. This "Yum" function is not in the current translation unit.
Therefore, granted that the project successfully compiles and links, "Yum"
must be in a different translation unit.

In agreement so far?

If this "Yum" function in translation unit A is visible from, can be called
from, can be referred to from; all from within translation unit B, then what
you've got there is the miracle of "external linkage".

The behavior is undefined. Maybe it is not calling any 'Yum's at all.


Chapter and Verse again, please.

One again, you have wrong idea about what "external linkage" is.
"External linkage" doesn't guarantee that function can be _called_ from
another translation unit. "External linkage" means that function can be
_referred_ from another translation units. What concrete ways of
"referring" are hiding behind this generic term depends on several
other factors. In your particular case "calling" function 'Yum' from
'cow.cpp' is not a legal way to "refer" to it. The fact that program
"compiles" means nothing (I'm actually surprised that you use the
"compilability" of the program as some kind of proof of it validity.)

That entire paragraph reads like bullshit to me. If a certain function in a
certain translation unit has external linkage, then you can do whatever the
hell you want to it from another translation unit - call it, refer to it,
takes it address, feed it ice-cream...

Trying to exploit the compiler's "security hole", which allows
"linking" to 'inline' functions from another translation unit, is a
recipe for disaster. Just don't do it.


The alleged security hole is in the C++ Standard, which allows multiple
definition of a function. Here's some deductive reasoning for you:

A) A function with a certain name and a certain list of arguments can be
defined but once. Any subsequent definitions of the aformentioned function
yield a "Multiple Definition" compile error.

B) An inline function *IS* a function, concordantly it abides to A above.
This is where the Standard begins to choke on its own puke, as I have
demonstrated with my sample project.


My conclusions:

Solution One: All inline functions be defined in header files and be
prefixed with "static inline".

Solution Two: All inline functions are defined in a CPP file with external
linkage. The compiler and linker, collaborating as a complinker, make inline
calls inline and outline calls outline.


-JKop
 
A

Andre Kostur

JKop said:
Andrey Tarasevich posted:


I disagree.

Chapter and verse, please.

Section 3.2
Try to keep up here:

You have a translation unit. From within it, a function called "Yum"
is called. This "Yum" function is not in the current translation unit.
Therefore, granted that the project successfully compiles and links,
"Yum" must be in a different translation unit.

Unfortunately since you've invoked undefined behaviour, who knows what
happens.
Chapter and Verse again, please.

Same chapter. 3.2
The alleged security hole is in the C++ Standard, which allows
multiple definition of a function. Here's some deductive reasoning for
you:

A) A function with a certain name and a certain list of arguments can
be defined but once. Any subsequent definitions of the aformentioned
function yield a "Multiple Definition" compile error.

Proceeding from a false premise. The compiler isn't required to issue a
diagnostic.
B) An inline function *IS* a function, concordantly it abides to A
above. This is where the Standard begins to choke on its own puke, as
I have demonstrated with my sample project.

Nope, you've violated the One Definition Rule. See section 3.2. Most
important is the last line:

"If the definitions of D do not satisfy these requirements, then the
behaviour is undefined."



Next question... are you seriously attempting to learn C++? Or are you
trying to do something else?
 
J

JKop

But didn't some-one say that inline functions are allowed a multiple
definition?


Is a C++ Standard compliant compiler allowed to compile whatever it likes?
For instance can it compile the following without giving any errors at all?:


#include <int main()
{
#include <iostream> chocolate;

++chocolate++ = 54;

return inline; ? 6 :? cout << "Hello World";>


If so, then yes, my sample code does in fact have a Multiple Definition.
Deductive Reasoning:

1) Multiple Definitions are Undefined Behaviour.

2) My code contains Multiple Definitions.

3) My code contains Undefined Behaviour.


What I would absolutely love an explanation to is this, why does the
following not compile:


int Yum(char)
{
std::cout << "monkey!";

return 't';
}

int Yum(char)
{
std::cout << "ape!";

return 'k';
}


while the following does:


inline int Yum(char)
{
std::cout << "monkey!";

return 't';
}

inline int Yum(char)
{
std::cout << "ape!";

return 'k';
}


Is it:

A) Because Standard C++ allows multiple definitions of inline functions. If
so, then my code is *not* undefined behaviour, as there's nothing undefined
about multiple defining an inline function.

B) Because g++ is shit?


-JKop
 
A

Andrey Tarasevich

JKop said:
I disagree.

Chapter and verse, please.

"Chapter and verse" was named here on numerous occasions. However, you
chose to ignore it. How is this time different? Anyway, 7.1.2/2 clearly
states that an inline function with external linkage must be declared
'inline' in every translation unit in which it appears. It also says
that it shall be _defined_ in every translation unit in which it is
used. The standard says nothing about the behavior in situations when
the above requirements are violated. This is undefined behavior, by
definition of 'undefined behavior' given in 1.3.12.
Try to keep up here:

You have a translation unit. From within it, a function called "Yum" is
called. This "Yum" function is not in the current translation unit.
Therefore, granted that the project successfully compiles and links, "Yum"
must be in a different translation unit.

In agreement so far?

No. The program is invalid. If some implementation manages to compile
it, it simply means that in one way or another it implements some
"default solution" for this situation. It could be just anything. It
might call some default "stub" function created specifically for this
type of situation. It might do something else. Strictly speaking, the
behavior that you observe in your experiment is not much different from
that.

Also, once again, the fact that certain implementation compiles it means
absolutely nothing. Some other implementation (including the next
version of this one) might refuse to compile it.
If this "Yum" function in translation unit A is visible from, can be called
from, can be referred to from; all from within translation unit B, then what
you've got there is the miracle of "external linkage".

No. It is nothing more than "successful" attempt to exploit the
aforementioned "security hole". Yes, this hole is there because of
"external linkage". But it could have been implemented in much safer
manner. The implementation that you are using decided to implement it in
unsafe manner. It is nothing more than a quality-of-implementation issue.
Chapter and Verse again, please.
Above.


That entire paragraph reads like bullshit to me. If a certain function in a
certain translation unit has external linkage, then you can do whatever the
hell you want to it from another translation unit - call it, refer to it,
takes it address, feed it ice-cream...

Well, you seem to throw the word "bullshit" around a lot these days.
And, may I notice, you've embarrassed yourself more than a few times
with it. I recommend you to get better understanding of C++ terminology
and forget about those frivolous interpretations of C++ terms you seem
to assume all the time. There's no point to continue this discussion
until you take care of this problem or at least acknowledge its existence.
The alleged security hole is in the C++ Standard, which allows multiple
definition of a function.

There's no security hole in the standard. The standard simply throws
this into the "undefined behavior" pile. The rest is a
quality-of-implementation issue.

Here's some deductive reasoning for you:
A) A function with a certain name and a certain list of arguments can be
defined but once. Any subsequent definitions of the aformentioned function
yield a "Multiple Definition" compile error.

B) An inline function *IS* a function, concordantly it abides to A above.
This is where the Standard begins to choke on its own puke, as I have
demonstrated with my sample project.

Not true. ODR consists of several sub-rules, directed at different
entities in the language. Sub-rule for inline functions is quite
different for sub-rule for ordinary functions. As far as ODR is
concerned, ordinary functions and inline functions are different beasts,
even though they both are called "functions".

What you do here is rather primitive demagogy. You substitute the
meanings of standard terms with something of your own concoction. And
then you try to see what will happen to certain portions of the document
if you interpret it within that new terminology of yours. The result
doesn't make any sense (not surprisingly). And now you call it "the
standard's own puke"? LOL
My conclusions:

Solution One: All inline functions be defined in header files and be
prefixed with "static inline".
Whatever.

Solution Two: All inline functions are defined in a CPP file with external
linkage. The compiler and linker, collaborating as a complinker, make inline
calls inline and outline calls outline.

Not C++.
 

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

No members online now.

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top