I follow this example http://www.tutorialspoint.com/cplusplus/cpp_inline_functions.htm:
#include <iostream>
using namespace std;
inline int Max(int x, int y)
{
return (x > y)? x : y;
}
// Main function for the program
int main( )
{
cout << "Max (20,10): " << Max(20,10) << endl;
cout << "Max (0,200): " << Max(0,200) << endl;
cout << "Max (100,1010): " << Max(100,1010) << endl;
return 0;
}
and tried removing the inline and still gives same results... so what does inline actually affect this?
inline has nothing whatsoever to do with the behavior of the function. The only thing it is required to do is alter the behavior of the linker, specifically to cause the linker to allow the same symbol to be defined in multiple translation units. inline never affects a program's observed behavior1, only whether or not it might link successfully.
In the past it was also used as a hint to the compiler that the function should be inlined whenever used, but this is not required by the C++ specification and modern compilers are very good at deciding whether to inline without input from the programmer.
In the code you have posted, inline will not have any observable effect.
1Unless you define a function multiple times differently in different translation units and declare them all inline -- but I think this invokes undefined behavior.
You can view the difference between your code's operation using assembly output.
To view this using g++ as a compiler, type:
g++ -S mySource.cpp -o assemblyWithInline
then remove your inline and try, for example,
g++ -S myNewSource.cpp -o assemblyWithoutInline
diff assemblyWithInline assemblyWithoutInline
This will display the difference between your two sets of code (as understood by your compiler, g++)
This may be the same, if your compiler optimises your code to automatically inline it.
The output in all cases will be the same, since your logic is not altered by the presence of an inline hint.
Inline is Just a hint for the compiler. It can provide somÄ™ measurable speed up of code making calls to Inline functions.
Modern compilers seam to be far more clever these days so they know in 99% situations where Inline would help and where code would suffer from such inline.
Basicly inlined function code is pasted at every (suitable) call instruction, reducing overhead of pushing and popping its arguments.
Related
I was experimenting with Clang 6.0's Memory Sanitizer(MSan).
Code is compiled with
clang++ memsans.cpp -std=c++14 -o memsans -g -fsanitize=memory -fno-omit-frame-pointer -Weverything
on Ubuntu 18.04. As per the MSan documentation
It will tolerate copying of uninitialized memory, and also simple
logic and arithmetic operations with it. In general, MemorySanitizer
silently tracks the spread of uninitialized data in memory, and
reports a warning when a code branch is taken (or not taken) depending
on an uninitialized value.
So the following code does not generate any error
#include <iostream>
class Test {
public:
int x;
};
int main() {
Test t;
std::cout << t.x;
std::cout << std::endl;
return 0;
}
But this will
#include <iostream>
class Test {
public:
int x;
};
int main() {
Test t;
if(t.x) {
std::cout << t.x;
}
std::cout << std::endl;
return 0;
}
Ideally one would like both of these code samples to generate some sort of error since both are "using" an uninitialised variable in the sense that the first one is printing it. This code is a small test code and hence the error in the first code is obvious, however if it were a large codebase with a similar error, MSan would totally miss this. Is there any hack to force MSan to report this type of error as well ?
It sounds like your C++ library wasn't built with MSan. Unlike ASan and UBSan, MSan requires that the whole program was built with msan enabled. Think of it like having a different ABI, you shouldn't link two programs built with different msan settings. The one exception is libc for which msan adds "interceptors" to make it work.
If you write your own code which you want to integrate with msan by reporting an error where msan normally wouldn't (say, in a function which makes a copy but you know the data needs to be initialized) then you can use __msan_check_mem_is_initialized from the msan_interface.h file: https://github.com/llvm-mirror/compiler-rt/blob/master/include/sanitizer/msan_interface.h
So I have this code in 2 separate translation units:
// a.cpp
#include <stdio.h>
inline int func() { return 5; }
int proxy();
int main() { printf("%d", func() + proxy()); }
// b.cpp
inline int func() { return 6; }
int proxy() { return func(); }
When compiled normally the result is 10. When compiled with -O3 (inlining on) I get 11.
I have clearly done an ODR violation for func().
It showed up when I started merging sources of different dll's into fewer dll's.
I have tried:
GCC 5.1 -Wodr (which requires -flto)
gold linker with -detect-odr-violations
setting ASAN_OPTIONS=detect_odr_violation=1 before running an instrumented binary with the address sanitizer.
Asan can supposedly catch other ODR violations (global vars with different types or something like that...)
This is a really nasty C++ issue and I am amazed there isn't reliable tooling for detecting it.
Pherhaps I have misused one of the tools I tried? Or is there a different tool for this?
EDIT:
The problem remains unnoticed even when I make the 2 implementations of func() drastically different so they don't get compiled to the same amount of instructions.
This also affects class methods defined inside the class body - they are implicitly inline.
// a.cpp
struct A { int data; A() : data(5){} };
// b.cpp
struct A { int data; A() : data(6){} };
Legacy code with lots of copy/paste + minor modifications after that is a joy.
The tools are imperfect.
I think Gold's check will only notice when the symbols have different types or different sizes, which isn't true here (both functions will compile to the same number of instructions, just using a different immediate value).
I'm not sure why -Wodr doesn't work here, but I think it only works for types, not functions, i.e. it will detect two conflicting definitions of a class type T but not your func().
I don't know anything about ASan's ODR checking.
The simplest way to detect such concerns is to copy all the functions into a single compilation unit (create one temporarily if needed). Any C++ compiler will then be able to detect and report duplicate definitions when compiling that file.
In a bit of serialization code for a project I'm working on I have a type whose size is compiler dependent. In order to deal with this, I decided to use a template specialization, which works great. Everything is resolved at compile time. The code looks a little bit like this (not the real code, just an example):
template <int size>
void
special_function()
{
std::cout << "Called without specialization: " << size << std::endl;
}
template <>
void
special_function<4>()
{
std::cout << "dword" << std::endl;
}
template <>
void
special_function<8>()
{
std::cout << "qword" << std::endl;
}
int
main()
{
special_function<sizeof(int)>();
return 0;
}
On my 32-bit system, executing the above program outputs dword, as expected. But the whole point of doing it this way and not just doing if (sizeof(int) == 4) { ... } else if ... is that I had hoped that the compiler would only produce code for the appropriate function. Since special_function<4> is the only one called in this program, I expected it to be the only one generated by the compiler (gcc 4.1.2 in this case, on x86 Linux).
But that is not the observed behavior.
While it indeed works, the code for each template specialization is generated despite not being ever used. The generic definition is not generated, however.
I should mention that this is a one-step compilation, not a compilation into intermediary object files followed by a link. In that case it would seem natural to defer dead code removal to the link stage, and I know that linkers are not always terribly good at this.
Does anyone know what is going on? Is there a subtlety of template specialization I'm missing here? Lord knows the devil is in the details with C++.
EDIT: Since it's been mentioned, this behavior occurs with both -O3 and -Os.
EDIT2: Rob below suggested putting the functions in an anonymous namespace. Doing so and compiling with any level of optimization does indeed remove the dead code, which is good. But I was curious, so I tried doing the same with the following program:
namespace {
void foo() { std::cout << "Foo!" << std::endl; }
void bar() { std::cout << "Bar!" << std::endl; }
}
int
main()
{
foo();
return 0;
}
The idea here is see whether or not Rob's solution is actually related to template specializations. As it turns out, the above code compiled with optimizations turned on elides the unused definition of bar() from the executable. So it seems that while his answer solves my immediate problem, it doesn't explain why template specializations that aren't used are compiled at all.
Does anyone know of a relevant snippet from the standard that would explain this? I always thought templates were generated only on use, but perhaps this is not so for full specializations ...
The template specializations in your example are functions with external linkage. The compiler cannot know that they won't be called from another translation unit.
On my g++ 4.7.2 Ubuntu system, placing the templates into an anonymous namespace and compiling with -O3 prevented the unused function from being generated.
Similarly, declaring the function template static had the desired effect.
This is a peculiar problem. I looked into it a little, and this issue is unrelated to template specialization. I guess g++ doesn't, by default, strip unused symbols. This makes sense in case you later want to link your output to another program.
However, there are command line options that you can use to strip unused symbols. For details, see this post:
How to remove unused C/C++ symbols with GCC and ld?
but also see here
Using GCC to find unreachable functions ("dead code")
and here
Dead code detection in legacy C/C++ project
Just to try this out, I modified the code as follows:
#include <iostream>
void junk_function() {
std::cout<<"test" << std::endl;
}
template <int size>
void special_function()
{
std::cout << "Called without specialization: " << size << std::endl;
}
template <>
void special_function<4>()
{
std::cout << "dword" << std::endl;
}
template <>
void special_function<8>()
{
std::cout << "qword" << std::endl;
}
int main()
{
special_function<sizeof(int)>();
return 0;
}
Then stored this code to sp.cpp. First,
g++ -Os sp.cpp -o sp
nm sp
and got this (note, I removed a bunch of symbols for readability):
0804879a T _Z13junk_functionv
080487b8 T _Z16special_functionILi4EEvv
080487f5 T _Z16special_functionILi8EEvv
Seems the two unused symbols are there. I also tried -O1, -O2, -O3, and got the same.
Next:
g++ -Os -fdata-sections -ffunction-sections sp.cpp -o sp -Wl,--gc-sections
nm sp
and got this:
0804875a T _Z16special_functionILi4EEvv
That's it. So it looks like you just need to pass the right arguments in to tell g++ to strip unused symbols. On mac, I guess they have the -dead_strip option, but I don't know why it doesn't work in g++ (even though it is mentioned in the man pages. Admittedly, I didn't dig into this, so there may be a fine print that I missed).
I think Visual C++'s linker strips by default when you link, but I didn't test. Maybe someone else can chime in.
#include <iostream>
#include <cstdlib>
int main() {
cout << "!!!Hello World!!!" << endl;
system("pause");
return main();
}
The above works, but it hardcoded the main() function. Is there a magic variable or macro to get the current running function?
Is it allowed in "C++"? No.
In practice, can you call main()? Yes.
Whatever the C++ Standard says, that doesn't stop the Linux g++ compiler from compiling code with main() in main().
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
int y = rand() % 10; // returns 3, then 6, then 7
cout << "y = " << y << endl;
return (y == 7) ? 0 : main();
}
Which lets us do:
> g++ g.cpp; ./a.out
y = 3
y = 6
y = 7
Looking in to the assembly, we see that main is called just like any other function would be:
main:
...
cmpl $7, -12(%rbp)
je .L7
call main
...
.L7:
...
leave
ret
Not that this behavior is guaranteed, but it looks like g++ doesn't seem to really care about the standard, apart from this sarcastic warning with -pedantic
g.cpp:8: error: ISO C++ forbids taking address of function '::main'
The C++ Standard says that you may not call main() from your own code. As for getting the name of the current function, you could use the __FUNCTION__ macro, but once again this is not standard:
#include <iostream>
using namespace std;
void foo() {
cout << __FUNCTION__ << endl;
}
int main() {
foo();
}
should print "foo" or something similar if __FUNCTION__ is supported.
If a specific implementation allows this, it is not behaving correctly(a). The standard state quite explicitly in C++14, 3.6.1 Main function /3:
The function main shall not be used within a program.
(a) Keep in mind that many implementations follow some parts of the standard loosely, preferring power over strictness. That can have the unfortunate side effect that your code may not be portable to other compilers or even other versions of the same compiler.
Many implementations will also allow you to take the stricter view, such as using g++ -std=c++11 -Werror=pedantic which catches the particular issue bought up in this question, as well as quite a few others. It is that "mode" of translation that allows implementations to claim to be compliant with the standard, as per 1.4 Implementation compliance:
If a program contains a violation of any diagnosable rule ..., a conforming implementation shall issue at least one diagnostic message.
You'll see it's still quite possible to allow the code to compile and run in that case, since "diagnostic message" can mean a warning rather than an error.
Generally, no. For now it will be enough for you to know that the compiler needs to know the exact function you're calling at the compile time. You cannot do magic like, let's say
func = "my_function";
func();
if the called function name will change during runtime. (There are exceptions and ways around that, but you don't need that).
Don't think about that as a case of hard-coding: it is not. If you need to call the function, then you just write its name, and don't try to abstract it, or something.
Also, now would be a nice way to learn about the while loop, infinite loops and write without the function calls at all, e.g
int main()
{
while (1) {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
system("pause");
}
}
Never turn your back on C++. It'll getcha.
I'm in the habit of writing unit tests for everything I do. As part of this I frequently define classes with names like A and B, in the .cxx of the test to exercise code, safe in the knowledge that i) because this code never becomes part of a library or is used outside of the test, name collisions are likely very rate and ii) the worst that could happen is that the linker will complain about multiply defined A::A() or what every and I'll fix that error. How wrong I was.
Here are two compilation units:
#include <iostream>
using namespace std;
// Fwd decl.
void runSecondUnit();
class A {
public:
A() : version( 1 ) {
cerr << this << " A::A() --- 1\n";
}
virtual ~A() {
cerr << this << " A::~A() --- 1\n";
}
int version; };
void runFirstUnit() {
A a;
// Reports 1, correctly.
cerr << " a.version = " << a.version << endl;
// If you uncomment these, you will call
// secondCompileUnit: A::getName() instead of A::~A !
//A* a2 = new A;
//delete a2;
}
int main( int argc, char** argv ) {
cerr << "firstUnit BEGIN\n";
runFirstUnit();
cerr << "firstUnit END\n";
cerr << "secondUnit BEGIN\n";
runSecondUnit();
cerr << "secondUnit END\n";
}
and
#include <iostream>
using namespace std;
void runSecondUnit();
// Uncomment to fix all the errors:
//#define USE_NAMESPACE
#if defined( USE_NAMESPACE )
namespace mySpace
{
#endif
class A {
public:
A() : version( 2 ) {
cerr << this << " A::A() --- 2\n";
}
virtual const char* getName() const {
cerr << this << " A::getName() --- 2\n"; return "A";
}
virtual ~A() {
cerr << this << " A::~A() --- 2\n";
}
int version;
};
#if defined(USE_NAMESPACE )
} // mySpace
using namespace mySpace;
#endif
void runSecondUnit() {
A a;
// Reports 1. Not 2 as above!
cerr << " a.version = " << a.version << endl;
cerr << " a.getName()=='" << a.getName() << "'\n";
}
Ok, ok. Obviously I shouldn't have declared two classes called A. My bad. But I bet you can't guess what happens next...
I compiled each unit, and linked the two object files (successfully) and ran. Hmm...
Here's the output (g++ 4.3.3):
firstUnit BEGIN
0x7fff0a318300 A::A() --- 1
a.version = 1
0x7fff0a318300 A::~A() --- 1
firstUnit END
secondUnit BEGIN
0x7fff0a318300 A::A() --- 1
a.version = 1
0x7fff0a318300 A::getName() --- 2
a.getName()=='A'
0x7fff0a318300 A::~A() --- 1
secondUnit END
So there are two separate A classes. In the second use, the destructor and constructor for the first on was used, even though only the second one was in visible in its compilation unit. Even more bizarre, if I uncomment the lines in runFirstUnit, instead of calling either A::~A, the A::getName is called. Clearly in the first use, the object gets the vtable for the second definition (getName is the second virtual function in the second class, the destructor the second in the first). And it even correcly gets the constructor from the first.
So my question is, why didn't the linker complain about the multiply defined symbols.
It appears to choose the first match. Reordering the objects in the link step confirm.
The behavior is identical in Visual Studio, so I'm guessing that this is some standard-defined behavior. My question is, why? Clearly it would be easy for the linker to barf given the duplicate names.
If I add,
void f() {}
to both files it complains. Why not for my class constructors and destructors?
EDIT The problem isn't, "what should I have done to avoid this", or "how is the behavior explained". It is, "why don't linkers catch it?" Projects may have thousands of compile units. Sensible naming practices don't really solve this issue -- they only make the problem obscure and only then if you can train everyone to follow them.
The above example leads to ambiguous behavior that is easy and definitively solvable by compiler tools. So, why do they not? Is this simply a bug. (I suspect not.)
** EDIT ** See litb's answer below. I'm repeating is back to make sure my understanding's right:
Linkers only generate warnings for strong references.
Because we have shared headers, inline function definitions (i.e. where declaration and definition is made at the same place, or template functions) are be compiled into multiple object files for each TU that sees them. Because there's no easy way to restrict the generation this code to a single object file, the linker has the job of choosing one of many definitions. So that errors are not generated by the linker, the symbols for these compiled definitions are tagged as weak references in the object file.
The compiler and linker relies on both classes to be exactly the same. In your case, they are different and so strange things happen. The one definition rule says that the result is undefined behavior - so behavior is not at all required to be consistent among compilers. . I suspect that in runFirstUnit, in the delete line, it puts a call to the first virtual table entry (because in its translation unit, the destructor may occupy the first entry).
In the second translation unit, this entry happens to point to A::getName, but in the first translation unit (where you execute the delete), the entry points to A::~A. Since these two are differently named (A::~A vs A::getName) you don't get a name clash (you will have code emitted for both the destructor and getName). But since their class name is the same, their v-tables will clash on purpose, because since both classes have the same name, the linker will think they are the same class and assume same contents.
Notice that all member functions were defined in-class, which means they are all inline functions. These functions can be defined multiple times in a program. In the case of in-class definitions, the rationale is that you may include the same class definition into different translation units from their header files. Your test function, however, isn't an inline function and thus including it into different translation units will triggers a linker error.
If you enable namespaces, there will be no clash what-so ever, because ::A and ::mySpace::A are different classes, and of course will get different v-tables.
A simple way to restrict each class to the current translation unit is to enclose it in an anonymous namespace:
// a.cpp
namespace {
class A {
// ...
};
}
// b.cpp
namespace {
class A {
// ...
};
}
is perfecetly legal. Because the two classes are in separate translation units, and are inside anonymous namespaces, they won't conflict.
The functions are defined as inline. inline functions can be defined multiple times in the program. See point 3 in the summary here:
http://en.wikipedia.org/wiki/One_Definition_Rule
The important point is:
For a given entity, each definition must be the same.
Try not defining the functions as inline. The linker should start to give duplicate symbol errors then.