Inserting function calls in the gimple - c++

I'm having problems figuring out how to do the next thing.
I have the following code:
test.cpp
#include <stdio.h>
void
function(void) {printf("Hellow ");}
int main(void) {
printf("World\n");
return 0;
}
And I want to transform it into the next one:
#include <stdio.h>
void
function(void) {printf("Hellow ");}
int main(void) {
function();
printf("World\n");
return 0;
}
with a gcc plugin.
The code that doesn't work in my plugin is this one:
...
tree function_fn;
tree function_fn_type;
function_fn_type=build_function_type_list(void_type_node, void_type_node, NULL_TREE);
function_fn = build_fn_decl ("function", function_fn_type);
gimple call = gimple_build_call (funcion_fn, 0);
gsi_insert_before (&gsi, call, GSI_NEW_STMT);
...
Then when I compile test.cpp with the plugin i have the next error message:
/tmp/cc2VRszt.o: In function main':
test.cpp:(.text+0x60): Undefined reference tofunction'
Anyone can help me?

You're building a function declaration, and inserting a call to a function based on the declaration, but unless you've defined that function in another translation unit you link to, it will be unresolved. If you want a plugin to insert a definition in the same translation unit like in your example, this guide for front-end developers would be a good start:
http://www.tldp.org/HOWTO/GCC-Frontend-HOWTO-7.html

Related

g++ compiler not generating error/warning for undefined methods

I have a class that has a declared method but not defined/used anywhere. I expected this piece of code to generate linking error but it did not. Looks like compiler is smart enough to remove dead code. Which default optimization is doing this? How can I explicitly disable it to generate the error?
#include <iostream>
using namespace std;
class Base{
public:
int x;
string name;
void set(int val){ x = val;};
int get(){ return x;}
void Init();
};
int main() {
Base base;
base.set(10);
cout << base.get() << endl;
return 0;
}
EDIT1: Here Init() function is not defined and neither used anywhere. So, I expected compiler to complain about this not defined. But don't see any error/warning.
Thanks in advance.
Generally the linker will only produce errors for undefined symbols that are used. As you never call Init there is no error.
Looks like compiler is smart enough to remove dead code.
The compiler is not even "smart" here. There is no code using a function so that function is not needed to produce an executable program.
The function is not even "ODR used" so technically the compiler would be wrong to require a definition.

Why does google test sample put tests in an anonymous namespace?

This is NOT a duplicate of Superiority of unnamed namespace over static?
Please read the question carefully before marking it as duplicate. I am not asking why use an unnamed namespace versus static!
I am asking, why are google tests placed inside an unnamed namespace? Is this some convention that google tests follow, and if so, why? The tests work fine whether they are in an unnamed namespace or not, so obviously it is not required.**
I cloned google test from github and built it for my mac. It works fine, but I noticed in the sample test code they give they place the tests in an unnamed namespace. Does anyone know why?
For example, see following file:
googletest/googletest/samples/sample1_unittest.cc
(https://github.com/google/googletest/blob/master/googletest/samples/sample1_unittest.cc#L41)
Part of the file looks like this:
// Step 1. Include necessary header files such that the stuff your
// test logic needs is declared.
//
// Don't forget gtest.h, which declares the testing framework.
#include <limits.h>
#include "sample1.h"
#include "gtest/gtest.h"
namespace {
// Step 2. Use the TEST macro to define your tests.
...
TEST(FactorialTest, Negative) {
// This test is named "Negative", and belongs to the "FactorialTest"
// test case.
EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1));
EXPECT_GT(Factorial(-10), 0);
}
...
} // namespace
Does anyone know why all the tests are in an unnamed namespace?
I tried removing the unnamed namespace and the sample still worked fine, so clearly it is not necessary for this particular sample.
I think the comment by Mike Kinghan answers the question, especially the part
You don't need to ask a programmer why haven't put stuff into the global namespace. You need to ask why they have.
However, I think its a good idea, pedagogically, to give an example of the kind of horrors that can happen if one doesn't follow good coding practices and as a consequence, violate ODR by mistake.
First, to relate the program below with the question, one needs to know that some of the Google Test macros create new classes. Now, consider the following program
myClass1.h
#ifndef MYCLASS1_H
#define MYCLASS1_H
int f();
#endif /* MYCLASS1_H */
myClass2.h
#ifndef MYCLASS2_H
#define MYCLASS2_H
int g();
#endif /* MYCLASS2_H */
myClass1.cpp
#include "myClass1.h"
class MyClass {
public:
void twice() { val *= 2; }
char val;
};
int f() {
MyClass x;
x.val = 2;
x.twice();
return x.val;
}
myClass2.cpp
#include "myClass2.h"
class MyClass {
public:
void twice() { val *= 2; }
double val;
};
int g() {
MyClass x;
x.val = 3;
x.twice();
return x.val;
}
main.cpp
#include <iostream>
#include "myClass1.h"
#include "myClass2.h"
int main() {
std::cerr << f() << std::endl << g() << std::endl;
return 0;
}
Notice how the class MyClass has two different definitions. With g++ 5.4.0-6ubuntu1~16.04.10, compiling and running the program with
g++ -O3 myClass1.cpp myClass2.cpp main.cpp -o undefined && ./undefined
prints 4 and 6, the expected behavior. However, compiling and running with no optimizations, i.e. with
g++ -O0 myClass1.cpp myClass2.cpp main.cpp -o undefined && ./undefined
prints 4 and 3!
Now, put this bug in a non-trivial program and you might easily loose an afternoon of debugging, especially if the bug laid dormant for a while. On the other hand, wrapping the classes in anonymous namespaces up-front takes no time at all and it prevents the bug. I think this illustrates one of the rationale behind some of the good coding practices: basic risk management.

function in main program OK, undefined references otherwise

I have a function, that when defined in the main file of my program, works as I wish, and produces a lot of undefined references, when defined in a header file.
This header file exists:
#include "Domain.h"
#include "Character.h"
class Item {
public:
Character input;
Item(Character c2);
};
Item pistol(int which, float strength);
The function that makes problems is pistol. It looks like
Item pistol(int which, float strength) {
Interval i = Interval(0, 1);
Domain d = Domain(i);
Character c = Character({d}, {1});
return Item(c);
}
When I try to link the code with my main program, all calls that refer to object in Domain.h and Character.h are undefined references, that means I get linking time errors like:
undefined reference to `Character::show()'
...
undefined reference to `Interval::Interval(float, float)'
...
these errors are at places in the code, which are not inside the pistol function.
When I move this function to my main program, everything works as expected:
#include "Domain.h"
#include "Character.h"
#include "Item.h"
Item pistol(int which, float strength) {
// definition, see above
}
int main() {
Item w2 = pistol(2, 0.5);
return 0;
}
What is the problem with that function being in Item.h/Item.cxx?
What do I need to do to put it their?
undefined reference is a linking stage error.
You most probably missed to link with a compilation unit, missed to recompile a dependent compilation unit, or tried to have a template class/function definition not seen by the compiler from all your compilation units using it!

can't understand the code that shedskin generates

for example I have a function in python that I want to convert to c++ (or call from c++ but I don't want to depend on python interpretor)
simple python function
//test.py
def my_sum(x,y):
print "Hello World!"
return x*x+y
I run shedskin and have
//test.cpp
#include "builtin.hpp"
#include "test.hpp"
namespace __test__ {
str *__name__;
void __init() {
__name__ = new str("__main__");
}
} // module namespace
int main(int, char **) {
__shedskin__::__init();
__shedskin__::__start(__test__::__init);
}
//test.hpp
#ifndef __TEST_HPP
#define __TEST_HPP
using namespace __shedskin__;
namespace __test__ {
extern str *__name__;
} // module namespace
#endif
ugly code and there is no my function my_sum and code depends on "builtin.hpp". is it possible to convert only function?
or
I want to call function from my c++ code something like
int sum= py.my_sum(3,5);
how can I do this?
or
maybe I can do DLL or Lib from python code that I can use in c++ code?
notice the warning that shedskin gives for this program:
*WARNING* test.py:1: function my_sum not called!
it is also mentioned in the documentation that for compilation to work, a function should be called (directly or indirectly), as it's not possible to do type inference otherwise.. how to determine the types of the arguments of my_sum, if there's not even a single call to it..? :-)
adding this, for example:
if __name__ == '__main__':
my_sum(1,1)
makes my_sum appear in the generated C++ code, which can potentially be called from another C++ program.

C++ linker error

I"m having some problem with the following program. The program implements a stack using a linked list. I'm not showing all my code here because the code is fine. But the problem I'm having is with linking different files together.
I'm using an IDE to run the program. When I run the TestIntStacks.cpp, the main method is supposed to call test() from StackFunctions.cpp. The test function (defined in StackFunctions.cpp), uses the TestStack class methods.
Currently I'm receiving an error saying "linker error, push/pop not defined". What I'm doing wrong? I'm sure it's something to do with a namespace.
MyStack.h
-------------------------------------
namespace A
{
class Node{
public :
char data;
StackNode* link;
StackNode(int v=0): data(v), link(NULL){ }
};
class MyStack{
private:
Node * top;
public:
MyStack():top(NULL){ }
void push(int c);
};
}//namespace
//TestStack.cpp
--------------------------------------------------------------
#include "MyStack.h"
namespace A
{
void MyStack::push(int x)
{
StackNode *temp = new StackNode(x);
temp->link = top;
top = temp;
}
}
//StackFunctions.cpp
-----------------------------------------------------------
#include <iostream>
#include "TestStack.h"
using namespace std;
using namespace A;
void test()
{
MyStack st;
st.push(1);
st.push(2);
st.push(3);
st.push(4);
}
// TestIntStacks.cpp
----------------------------------------------------------------
// Code for testing the TestStack
// from the A namespace.
#include <iostream>
#include <vector>
using namespace std;
#include "TestStack"
#include "StackFunctions.cpp"
void test();
int main()
{
test();
system("pause");
return 0;
}
You are defining push() and pop() methods in your header file TestStack.h, but you've not provided implementations for them in TestStack.cpp. You need to add the code that does the push and pop operations on your object.
This error seems pretty clear to me. You declared push() and pop() in your header file, but the linker could not find where these methods are implemented.
Where are they defined?
I think it has to do with the arguments provided to linker. For example, a similar error occurs when you use Visual C++ 6 in a following way. Let's say you created .cpp and .h files for a class. If you do not include cpp file into your project you get the similar error. Because the IDE does not determine the source file based on the provided header file. I don't know about dev-c++ IDE, but the solution might be similar. The problem is you compile (or not) TestStack.cpp and the output of this compiling is not provided to the linker, so the linker can't find the implementation.
You need to force the build script to use both cpp files. If you wrote your own make file, you need to build intermediate objects for each source, and then link at the end.
I suspect DEV-C++ doesnt automatically generate object files or try to link everything together.