473,385 Members | 1,830 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Scope of inline functions

I though that inline functions should be always visible only in the
compilation unit where they are defined - meaning if compiler cannot inline
them, they should be handled as if declared static. However sample attached
shows VC compiler does not work this way (tested in .NET 2003). When you
compile the sample with inlining enabled (like in default Release config),
the output is A1 = 1, A2 = 2. When run with inlining disabled (Debug),
output is A1 = 1, A2 = 1 - the compiler/linker uses the same version of the
A function in both compilation units, and it even gives no warning.

When I use "static inline" instead of "inline" for both A functions, it
works as expected. When I do not use any qualification (or use extern), the
linker gives error A is defined twice. My conclusion is current behaviour
with"inline" is both inconsistend and unsafe, as any compilation unit may
unknowningly use different inline function in case inline function is not
inlined (which is somethnig compiler is free to decide, and it is normal in
debug builds).

I recently experienced very similiar issue with global operator new - even
if it was inlined, it was shared accross various modules, leading to
unexpected behaviour. The issue was quite confusing, as I did not expect at
all other modules (in this case static libraries) could see my (inlined)
definition of operator new.

Regards
Ondrej

---------------------------------------
Ondrej Spanel
Lead Programmer
Bohemia Interactive Studio
www.bistudio.com
www.flashpoint1985.com
////////////////////////////////////////////////////////////////////////////
////////////
/// first.cpp
#include <stdio.h>
inline int A()
{
return 1;
}
int CallA2();

int CallA1()
{
return A();
}
int main(int argc, const char *argv[])
{
printf("A1 = %d\n",CallA1());
printf("A2 = %d\n",CallA2());
getchar();
return 0;
}
/// end of first.cpp

////////////////////////////////////////////////////////////////////////////
////////////
/// second.cpp
inline int A()
{
return 2;
}
int CallA2()
{
return A();
}
/// end of second.cpp
Nov 16 '05 #1
5 1927
Can anyone please confirm if this is bug (seems like that to me), or is
there some problem in the code provided?

Regards
Ondrej

"Ondrej Spanel" <on***********@bistudionospam.com> wrote in message
news:eT*************@TK2MSFTNGP11.phx.gbl...
I though that inline functions should be always visible only in the
compilation unit where they are defined - meaning if compiler cannot inline them, they should be handled as if declared static. However sample attached shows VC compiler does not work this way (tested in .NET 2003). When you
compile the sample with inlining enabled (like in default Release config),
the output is A1 = 1, A2 = 2. When run with inlining disabled (Debug),
output is A1 = 1, A2 = 1 - the compiler/linker uses the same version of the A function in both compilation units, and it even gives no warning.

When I use "static inline" instead of "inline" for both A functions, it
works as expected. When I do not use any qualification (or use extern), the linker gives error A is defined twice. My conclusion is current behaviour
with"inline" is both inconsistend and unsafe, as any compilation unit may
unknowningly use different inline function in case inline function is not
inlined (which is somethnig compiler is free to decide, and it is normal in debug builds).

I recently experienced very similiar issue with global operator new - even
if it was inlined, it was shared accross various modules, leading to
unexpected behaviour. The issue was quite confusing, as I did not expect at all other modules (in this case static libraries) could see my (inlined)
definition of operator new.

Regards
Ondrej

---------------------------------------
Ondrej Spanel
Lead Programmer
Bohemia Interactive Studio
www.bistudio.com
www.flashpoint1985.com
//////////////////////////////////////////////////////////////////////////// ////////////
/// first.cpp
#include <stdio.h>
inline int A()
{
return 1;
}
int CallA2();

int CallA1()
{
return A();
}
int main(int argc, const char *argv[])
{
printf("A1 = %d\n",CallA1());
printf("A2 = %d\n",CallA2());
getchar();
return 0;
}
/// end of first.cpp

//////////////////////////////////////////////////////////////////////////// ////////////
/// second.cpp
inline int A()
{
return 2;
}
int CallA2()
{
return A();
}
/// end of second.cpp

Nov 16 '05 #2
"Ondrej Spanel" <on***********@bistudionospam.com> wrote:
I though that inline functions should be always visible only in the
compilation unit where they are defined - meaning if compiler cannot inline
them, they should be handled as if declared static. However sample attached
shows VC compiler does not work this way (tested in .NET 2003). When you
compile the sample with inlining enabled (like in default Release config),
the output is A1 = 1, A2 = 2. When run with inlining disabled (Debug),
output is A1 = 1, A2 = 1 - the compiler/linker uses the same version of the
A function in both compilation units, and it even gives no warning.

When I use "static inline" instead of "inline" for both A functions, it
works as expected. When I do not use any qualification (or use extern), the
linker gives error A is defined twice. My conclusion is current behaviour
with"inline" is both inconsistend and unsafe, as any compilation unit may
unknowningly use different inline function in case inline function is not
inlined (which is somethnig compiler is free to decide, and it is normal in
debug builds).

I recently experienced very similiar issue with global operator new - even
if it was inlined, it was shared accross various modules, leading to
unexpected behaviour. The issue was quite confusing, as I did not expect at
all other modules (in this case static libraries) could see my (inlined)
definition of operator new.

Regards
Ondrej

---------------------------------------
Ondrej Spanel
Lead Programmer
Bohemia Interactive Studio
www.bistudio.com
www.flashpoint1985.com
////////////////////////////////////////////////////////////////////////////
////////////
/// first.cpp
#include <stdio.h>
inline int A()
{
return 1;
}
int CallA2();

int CallA1()
{
return A();
}
int main(int argc, const char *argv[])
{
printf("A1 = %d\n",CallA1());
printf("A2 = %d\n",CallA2());
getchar();
return 0;
}
/// end of first.cpp

////////////////////////////////////////////////////////////////////////////
////////////
/// second.cpp
inline int A()
{
return 2;
}
int CallA2()
{
return A();
}
/// end of second.cpp


--
MVP VC++ FAQ: http://www.mvps.org/vcfaq
Nov 16 '05 #3

"Ondrej Spanel" <on***********@bistudionospam.com> skrev i meddelandet
news:eL**************@TK2MSFTNGP09.phx.gbl...
Can anyone please confirm if this is bug (seems like that to me), or is there some problem in the code provided?
No, it is not a bug. The problem is with your code.

Inline does not change the visiblity of the function, it just hints
the compiler that you want it inlined, if possible. C++ has a "one
definition rule" which says you are allowed to repeat the definition
of an inlines function, provided that all definitions are the same. In
your case they are obviously not.

*If* all functions are inlined, you might get away with the error,
because it is hard to detect the it. It is still an error though.
If you want functions local to a specific cpp-file, you can put them
in an anonymous namespace. That hides them from the outside (by
generating a unique name).
Bo Persson

Regards
Ondrej

"Ondrej Spanel" <on***********@bistudionospam.com> wrote in message
news:eT*************@TK2MSFTNGP11.phx.gbl...
I though that inline functions should be always visible only in the compilation unit where they are defined - meaning if compiler cannot
inline
them, they should be handled as if declared static. However sample attached
shows VC compiler does not work this way (tested in .NET 2003).

When you compile the sample with inlining enabled (like in default Release config), the output is A1 = 1, A2 = 2. When run with inlining disabled (Debug), output is A1 = 1, A2 = 1 - the compiler/linker uses the same version of the
A function in both compilation units, and it even gives no
warning.
When I use "static inline" instead of "inline" for both A functions, it works as expected. When I do not use any qualification (or use extern), the
linker gives error A is defined twice. My conclusion is current
behaviour with"inline" is both inconsistend and unsafe, as any compilation unit may unknowningly use different inline function in case inline function is not inlined (which is somethnig compiler is free to decide, and it is normal in
debug builds).

I recently experienced very similiar issue with global operator
new - even if it was inlined, it was shared accross various modules, leading to unexpected behaviour. The issue was quite confusing, as I did not expect at
all other modules (in this case static libraries) could see my

(inlined) definition of operator new.

Regards
Ondrej

---------------------------------------
Ondrej Spanel
Lead Programmer
Bohemia Interactive Studio
www.bistudio.com
www.flashpoint1985.com

//////////////////////////////////////////////////////////////////////
//////
////////////
/// first.cpp
#include <stdio.h>
inline int A()
{
return 1;
}
int CallA2();

int CallA1()
{
return A();
}
int main(int argc, const char *argv[])
{
printf("A1 = %d\n",CallA1());
printf("A2 = %d\n",CallA2());
getchar();
return 0;
}
/// end of first.cpp

//////////////////////////////////////////////////////////////////////
//////
////////////
/// second.cpp
inline int A()
{
return 2;
}
int CallA2()
{
return A();
}
/// end of second.cpp



Nov 16 '05 #4
> No, it is not a bug. The problem is with your code.

Inline does not change the visiblity of the function, it just hints
the compiler that you want it inlined, if possible. C++ has a "one
definition rule" which says you are allowed to repeat the definition
of an inlines function, provided that all definitions are the same. In
your case they are obviously not.


Thank you for your explanation. I searched the net and came to the same
conclusion. However there is still one thing which I am convinced is a bug
in Visual C++ - and that is that the problem in my code in undetected and
"random" function implementation is selected of those I provided. I would
expect to get some linker error or warning in such situation - and I think
it should be quite easy for the linker to see the two definitions are not
the same (maybe I am mistaken in this)?

Regards
Ondrej
"Ondrej Spanel" <on***********@bistudionospam.com> wrote in message
news:eT*************@TK2MSFTNGP11.phx.gbl...
I though that inline functions should be always visible only in the compilation unit where they are defined - meaning if compiler cannot
inline
them, they should be handled as if declared static. However sample

attached
shows VC compiler does not work this way (tested in .NET 2003).

When you compile the sample with inlining enabled (like in default Release config), the output is A1 = 1, A2 = 2. When run with inlining disabled (Debug), output is A1 = 1, A2 = 1 - the compiler/linker uses the same version of
the
A function in both compilation units, and it even gives no

warning.
When I use "static inline" instead of "inline" for both A functions, it works as expected. When I do not use any qualification (or use extern),
the
linker gives error A is defined twice. My conclusion is current

behaviour with"inline" is both inconsistend and unsafe, as any compilation unit may unknowningly use different inline function in case inline function is not inlined (which is somethnig compiler is free to decide, and it is normal
in
debug builds).

I recently experienced very similiar issue with global operator

new - even if it was inlined, it was shared accross various modules, leading to unexpected behaviour. The issue was quite confusing, as I did not expect
at
all other modules (in this case static libraries) could see my

(inlined) definition of operator new.

Regards
Ondrej

---------------------------------------
Ondrej Spanel
Lead Programmer
Bohemia Interactive Studio
www.bistudio.com
www.flashpoint1985.com

//////////////////////////////////////////////////////////////////////
//////
////////////
/// first.cpp
#include <stdio.h>
inline int A()
{
return 1;
}
int CallA2();

int CallA1()
{
return A();
}
int main(int argc, const char *argv[])
{
printf("A1 = %d\n",CallA1());
printf("A2 = %d\n",CallA2());
getchar();
return 0;
}
/// end of first.cpp

//////////////////////////////////////////////////////////////////////
//////
////////////
/// second.cpp
inline int A()
{
return 2;
}
int CallA2()
{
return A();
}
/// end of second.cpp


Nov 16 '05 #5

"Ondrej Spanel" <on***********@bistudionospam.com> skrev i meddelandet
news:%2***************@TK2MSFTNGP11.phx.gbl...
No, it is not a bug. The problem is with your code.

Inline does not change the visiblity of the function, it just hints
the compiler that you want it inlined, if possible. C++ has a "one
definition rule" which says you are allowed to repeat the definition of an inlines function, provided that all definitions are the same. In your case they are obviously not.
Thank you for your explanation. I searched the net and came to the

same conclusion. However there is still one thing which I am convinced is a bug in Visual C++ - and that is that the problem in my code in undetected and "random" function implementation is selected of those I provided. I would expect to get some linker error or warning in such situation - and I think it should be quite easy for the linker to see the two definitions are not the same (maybe I am mistaken in this)?
It is not really a bug, even though I agree that it would be nice if
the linker warned you.

The problem is that the linker isn't required to be C++ specific, only
the compiler is. On some systems the same linker is used for all
compilers, so the C++ cannot put any language specific requirements on
it.

Also, by not following the "one definition rule" technically you have
broken the contract with the compiler, and it can do just anything at
all. Issuing a warning is definitely allowed, but not required.
Bo Persson


Regards
Ondrej
"Ondrej Spanel" <on***********@bistudionospam.com> wrote in message news:eT*************@TK2MSFTNGP11.phx.gbl...
> I though that inline functions should be always visible only in
the
> compilation unit where they are defined - meaning if compiler

cannot
inline
> them, they should be handled as if declared static. However
sample attached
> shows VC compiler does not work this way (tested in .NET

2003). When you
> compile the sample with inlining enabled (like in default
Release config),
> the output is A1 = 1, A2 = 2. When run with inlining disabled

(Debug),
> output is A1 = 1, A2 = 1 - the compiler/linker uses the same

version of
the
> A function in both compilation units, and it even gives no

warning.
>
> When I use "static inline" instead of "inline" for both A

functions, it
> works as expected. When I do not use any qualification (or use

extern),
the
> linker gives error A is defined twice. My conclusion is
current behaviour
> with"inline" is both inconsistend and unsafe, as any
compilation unit may
> unknowningly use different inline function in case inline
function is not
> inlined (which is somethnig compiler is free to decide, and it
is normal
in
> debug builds).
>
> I recently experienced very similiar issue with global
operator new - even
> if it was inlined, it was shared accross various modules,
leading to
> unexpected behaviour. The issue was quite confusing, as I did
not expect
at
> all other modules (in this case static libraries) could see my

(inlined)
> definition of operator new.
>
> Regards
> Ondrej
>
> ---------------------------------------
> Ondrej Spanel
> Lead Programmer
> Bohemia Interactive Studio
> www.bistudio.com
> www.flashpoint1985.com
>
>
>

////////////////////////////////////////////////////////////////////// //////
> ////////////
> /// first.cpp
> #include <stdio.h>
> inline int A()
> {
> return 1;
> }
> int CallA2();
>
> int CallA1()
> {
> return A();
> }
> int main(int argc, const char *argv[])
> {
> printf("A1 = %d\n",CallA1());
> printf("A2 = %d\n",CallA2());
> getchar();
> return 0;
> }
> /// end of first.cpp
>
>

////////////////////////////////////////////////////////////////////// //////
> ////////////
> /// second.cpp
> inline int A()
> {
> return 2;
> }
> int CallA2()
> {
> return A();
> }
> /// end of second.cpp
>
>



Nov 16 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: A | last post by:
Hi, I'm having problems completing a project in C++. I have been using inline functions in some of my header files. I have only done so for simple functions that only have 1 statement (eg....
3
by: Andy | last post by:
Someone supposedly knowledgeable tells me that any member function declared in class scope is automatically inlined. I am a little skeptical about this claim. Is this true (I know it cannot be ......
14
by: Chris Mantoulidis | last post by:
I am not clear with the use of the keyword inline... I believe you add it do a function when you implement the function inside the header file where the class is stored... But is that all? What...
47
by: Richard Hayden | last post by:
Hi, I have the following code: /******************************** file1.c #include <iostream> extern void dummy(); inline int testfunc() {
21
by: Rubén Campos | last post by:
I haven't found any previous message related to what I'm going to ask here, but accept my anticipated excuses if I'm wrong. I want to ask about the real usefulness of the 'inline' keyword. I've...
7
by: Srini | last post by:
Hello, Rules for inline functions say that they have to be defined in the same compilation unit as their declarations. For class member functions this means that the inline member functions must...
43
by: Patrick Laurent | last post by:
Hello I have a program with many many inlined template functions It is essential for the execution speed that every (or almost every) function marked as inlined, becomes really inlined by the...
4
by: Peter Ammon | last post by:
I would like to share a variable between two functions defined in two separate source files; no other functions will need the global variable so I'd prefer to not give it file scope. Thus, I want...
2
by: DaTurk | last post by:
Hi, I have an interesting issue, well, it's not really an issue, but I'd like to understand the mechanics of what's going on. I have a file, in CLI, which has a class declared, and a static...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.