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 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
"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
"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
> 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
"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 > >
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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....
|
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 ......
|
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...
|
by: Richard Hayden |
last post by:
Hi,
I have the following code:
/******************************** file1.c
#include <iostream>
extern void dummy();
inline int testfunc() {
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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,...
|
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$) {
}
...
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
| |