C++ - Compile and link multiple files - c++

I have a project with the following structure:
Item.cpp
Item.h
main.cpp
Makefile
The following source code is in the Item.h file:
class Item {
public:
Item();
~Item();
};
The following source code is in the Item.cpp file:
#include <iostream>
#include "Item.h"
Item::Item() {
std::cout << "Item created..." << std::endl;
}
Item::~Item() {
std::cout << "Item destroyed..." << std::endl;
}
The following source code is the content of the main.cpp file:
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1();
std::cout << "Hello world!" << std::endl;
return 0;
}
And finally, the following source code is the Makefile file:
CXX = g++
all: main item
$(CXX) -o sales.o main.o Item.o
main:
$(CXX) -c main.cpp
item:
$(CXX) -c Item.cpp
clean:
rm -rf *.o
When I run the make command and then I run the compiled code with the command ./sales.o, I get the following output:
Initialize program...
Hello world!
Why is the output of the constructor method of the class Item not printed in the console? I found in some web pages that you can compile the source codes in steps and then you can link it with the -o option when using g++ but it does not work in this case. How can I compile this source codes step by step and then link it in the Makefile?

I'm surely you ignored this warning :
warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1;
std::cout << "Hello world!" << std::endl;
return 0;
}
just remove parentheses it will be work
test : https://godbolt.org/z/KrdrhvsrW

Related

GCOV/LCOV ignores `used functions` declared before an `unused function`

The question may seem weird.
I tried to use GCOV/LCOV for my small project and practiced with simple code before applying it. While practicing it, I encountered an error that I had no idea how to solve.
The report created by LCOV showed that the functions declared before the unused function inside the source code file are reported as unused functions. In contrast, the functions displayed correct outputs when the binary file was executed.
The followings are actual codes used for the practice.
# makefile
CC = g++
CFLAG = -g -fPIC -fprofile-arcs -ftest-coverage
RM = rm -rf
main.o : main.cpp
$(CC) $(CFLAG) -c -Wall -Werror main.cpp
dummy_class.o : dummy_class.cpp
$(CC) $(CFLAG) -c -Wall -Werror dummy_class.cpp
build : main.o dummy_class.o
$(CC) $(CFLAG) -o main main.o dummy_class.o
gcov: main.cpp dummy_class.cpp
gcov main.cpp dummy_class.cpp
coverage.info: gcov
lcov --capture --directory . --output-file coverage.info
lcov -remove coverage.info "/usr/include/*" "/usr/local/include/*" --output-file coverage.info
report : coverage.info
genhtml coverage.info --output-directory ./out
clean :
rm -f main
rm -f *.o *.so *.gcno *.gcda *.gcov coverage.info
rm -r out
do :
make build
./main
make report
// dummy_class.hpp
#pragma once
void func_even_case(void);
void func_odd_case(void);
void func_not_reachable(void);
void dummy(void);
void dummy2(void);
void dummy3(void);
// dummy_class.cpp
#include <iostream>
#include <vector>
#include "dummy_class.hpp"
void func_even_case(void)
{
std::cout << "This is even case" << std::endl;
}
void func_odd_case(void)
{
std::cout << "This is odd case" << std::endl;
}
void func_not_reachable(void)
{
std::cout << "This is not reachable" << std::endl;
}
void dummy(void)
{
std::cout << "This is dummy1." << std::endl;
}
void dummy2(void)
{
std::cout << "This is dummy2." << std::endl;
}
void dummy3(void)
{
std::cout << "This is dummy3." << std::endl;
}
// main.cpp
#include <iostream>
#include "dummy_class.hpp"
int main(void)
{
for (int i = 0; i < 10; ++i)
{
if (i % 2 == 0)
{
func_even_case();
}
else if (i % 2 != 0)
{
func_odd_case();
}
else
{
func_not_reachable();
}
}
func_not_reachable();
dummy();
dummy2();
dummy3();
return 0;
}
When func_not_reachable() is placed outside the for-loop, the report returns
Overall coverage rate:
lines......: 96.7% (29 of 30 lines)
functions..: 100.0% (7 of 7 functions)
and the result is expected.
When func_not_reachable() is removed, the expected result was
Overall coverage rate:
lines......: 86.5% (25 of 29 lines)
functions..: 100.0% (6 of 7 functions)
since func_not_reachable() is the one that will not be executed.
However, the actual result was
Overall coverage rate:
lines......: 65.5% (19 of 29 lines)
functions..: 57.1% (4 of 7 functions)
If the dummy_class.cpp is modified as following
#include <iostream>
#include <vector>
#include "dummy_class.hpp"
void func_even_case(void)
{
std::cout << "This is even case" << std::endl;
}
void func_odd_case(void)
{
std::cout << "This is odd case" << std::endl;
}
void dummy(void)
{
std::cout << "This is dummy1." << std::endl;
}
void dummy2(void)
{
std::cout << "This is dummy2." << std::endl;
}
void dummy3(void)
{
std::cout << "This is dummy3." << std::endl;
}
// unused function declared at the end of the source code.
void func_not_reachable(void)
{
std::cout << "This is not reachable" << std::endl;
}
The report result becomes follows.
Overall coverage rate:
lines......: 34.5% (10 of 29 lines)
functions..: 14.3% (1 of 7 functions)
I am sure I made errors while using GCOV and LCOV, but I cannot figure out where I made a mistake.
Can someone tell me where I made a mistake?
The above code was executed on the following.
Ubuntu 20.04.4 LTS
g++ (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
gcov (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
lcov: LCOV version 1.14
Find out the source of the problem.
The problem was related to the compiler (g++ 11.1.0) or gcov (9.3.0) I used.
The code coverage reported the correct result when the compiler changed from g++ to clang.
To ensure the problem is related to the specific version of the compiler (g++ 11.1.0), I upgraded the system from Ubuntu 20.04.4 LTS to Ubuntu 22.04.4 LTS.
The test condition became as follow
Ubuntu 22.04.4 LTS
g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0
gcov (Ubuntu 11.2.0-19ubuntu1) 11.2.0
After the update had been made, the code coverage reported the correct result with g++.

How to create/implement an interceptor library correctly in C++?

This is my very firt post! I have implemented a small C++ program which uses the foo-implementation as a shared library. The shared library contains two functions: get_number() and print_text().
The goal is that a interceptor library (shared library) changes the functions of the foo-library, such that
get_number() should be replaced with a function that always returns 333.
print_text() should be wrapped so that some text is printed before and after the original function is executed.
The source code is the following:
foo.hpp
#ifndef _FOO_HPP
#define _FOO_HPP
namespace foo {
int get_number();
void print_text();
}
#endif
foo.cpp
#include "foo.hpp"
#include <iostream>
namespace foo {
int get_number()
{
return 13;
}
void print_text()
{
std::cout << "Hello World!" << std::endl;
}
}
interceptor.hpp
#ifndef _INTERCEPTOR_HPP
#define _INTERCEPTOR_HPP
#include <iostream>
namespace interceptor {
int get_number();
void print_text();
}
#endif
interceptor.cpp
#include "interceptor.hpp"
namespace interceptor {
int get_number()
{
return 333;
}
void print_text()
{
// Print here some text.
std::cout << "Hello World!" << std::endl;
// Print here some test.
}
}
main.cpp
#include <iostream>
#include "foo.hpp"
int main(void)
{
std::cout << "Number: " << foo::get_number() << "\n" << std::endl;
foo::print_text();
return 0;
}
Running the main-executable with and without the interceptor library could look like this:
$ ./main
Number: 13
Hello World!
$ LD_PRELOAD=$PWD/interceptor.so ./main
Number: 333
Hi before
Hello World!
Bye after
I'm a beginner in shared libraries and in interceptor libraries.
I hope that someone can help me with my problem.
To link main.o with foo.so do e.g.:
g++ -o main main.o foo.so
If you then try to run
./main
you will get an error, because foo.so is not in the system library path where the dynamic linker looks for it. We can tell it to look in the current folder as well:
$ LD_LIBRARY_PATH=. ./main
Number: 13
Hello World!
Now with the interceptor.so:
$ LD_LIBRARY_PATH=. LD_PRELOAD=interceptor.so ./main
Number: 13
Hello World!
As you can see nothing changed. This is because your interceptor.so does not actually contain definitions for foo::get_number and foo::print_text. It contains definitions for interceptor::get_number and interceptor::print_text, but these are never called by main!
interceptor.cpp should implement the same functions as foo.cpp, so after replacing namespace interceptor with namespace foo everywhere and recompiling:
$ LD_LIBRARY_PATH=. LD_PRELOAD=interceptor.so ./main
Number: 333
Hello World!

Use Cygwin compiled dll from windows

I need to use cygwin compiled dll from visual studio C++ or Code:blocks MinGW.
I tried use this simple example
#include <stdio.h>
int MyFunc()
{
printf("Printed from cygwin dll");
return 0;
}
And this makefile
obj = mydll.o
ALLLIBS = \
mydll.a \
mydll.dll
all: $(ALLLIBS)
mydll.a: $(obj)
$(LINK.a)
mydll.dll: $(obj)
$(cygTest.dll)
cygTest.dll = gcc -shared -o cygTest.dll \
-Wl,--out-implib \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive $(obj) \
-Wl,--no-whole-archive
mydll.a = ar $(ARFLAGS) $# $%
I am trying to call the final dll here.
#include <windows.h>
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
typedef int(*FnP_MyFunc)();
typedef void(*FnP_CYGWIN_DLL_INIT)();
int main()
{
FnP_MyFunc fnMyFunc;
HMODULE hLib, hGetCygwinIDDLL = LoadLibrary(TEXT("C:\\cygwin64\\bin\\cygwin1.dll"));
if (hGetCygwinIDDLL)
{
FnP_CYGWIN_DLL_INIT init = (FnP_CYGWIN_DLL_INIT)GetProcAddress(hGetCygwinIDDLL, "cygwin_dll_init");
init();
std::cout << "init complete " << endl;
}
int a;
hLib = LoadLibrary(TEXT("C:\\cygwin64\\home\\azatyan\\TestDynamicLink\\cygTest.dll"));
if (hLib)
{
std::cout << "From wrapper dll " << std::endl;
fnMyFunc = (FnP_MyFunc)GetProcAddress(hLib, "MyFunc");
a = fnMyFunc();
cout << a;
}
FreeLibrary(hGetCygwinIDDLL);
FreeLibrary(hLib);
return 0;
}
And it just hangs when it reaches to my MyFunc function. Or exits with code 1536..
Can anybody help me, what am I doing wrong?
UPDATE: I have tried the same without printf() function, worked ok, returned expected value, this means that the problem is in dependency libraries, but still I don't know haw I can add all dependency libraries..

"No such file or directory" Error when doing simple fstream in c++ while using makefile

I get the error "No such file or directory" when I run this at the top of my main:
Edit- This is my complete .cpp file:
#include <iostream>
#include <fstream>
#include <sstream>
#include "CommunicationNetwork.h"
using namespace std;
int DisplayMenu();
int main(int argc, char* argv[])
{
ifstream file;
string data;
file.open("message.txt");
if(file.is_open()){
cout << "WORKS" << endl;
}else {
cerr << "Error: " << strerror(errno) << endl;
}
CommunicationNetwork network;
bool gbye = false;
while(gbye == false){
int use = DisplayMenu();
switch(use) {
case 1:
network.buildNetwork();
break;
case 2:
network.printNetwork();
break;
case 3:
network.transmitMsg("message.txt");
break;
case 4: cout << "Add" << endl;
break;
case 5:
cout << "Goodbye!" << endl;
gbye = true;
}
}
return 0;
}
I have used this method countless times to open txt files but this is the first time I am using a makefile with my program which I'm guessing is the cause of the problem.
Does "message.txt" need to appear in my makefile somewhere? Is so where? What if I want to pass the filename as a command line argument?
My makefile looks like:
PROG = com
CC = g++
OBJS = CommunicationNetwork.o Assignment.o
CPPFLAGS = -Wall -std=c++11
$(PROG) : $(OBJS)
$(CC) -o $(PROG) $(OBJS)
CommunicationNetwork.o : CommunicationNetwork.h
$(CC) $(CPPFLAGS) -c CommunicationNetwork.cpp
Assignment.o :
$(CC) $(CPPFLAGS) -c Assignment.cpp
clean:
$(RM) $(PROG) $(OBJS)
The .txt file is saved in the same folder as my other files. I will get the error regardless of what .txt file I try. Let me know if more information is needed. Thanks!
Edit:
Both the .cpp and the .txt file are in the folder Assignment
for message.txt: /Users/tannerquigley/Library/Mobile Documents/com~apple~CloudDocs/School/CSCI 2270/Assignment
for Assignment.cpp: /Users/tannerquigley/Library/Mobile Documents/com~apple~CloudDocs/School/CSCI 2270/Assignment
in Terminal: res1-131-132-dhcp:Assignment tannerquigley$ make after I run a make clean
And then I open the "com" executable file that appears in the Assignment folder
Do not run the Unix Executable File that appears in the Folder. Run the program from the same terminal window using the command ./com or whatever you (I) named the program in the Makefile.

mysql-connector-c++ - ‘get_driver_instance’ is not a member of ‘sql::mysql’

I am a beginner at c++ and figured the only way I am going to learn is to get dirty with some code. I am trying to build a program that connects to a mysql database. I am using g++, on linux. With no ide.
I run "make" and this is my error:
hello.cpp:38: error: ‘get_driver_instance’ is not a member of ‘sql::mysql’
make: *** [hello.o] Error 1
Here is my code including makefile. Any Help would be great! Thanks in advance
###BEGIN hello.cpp###
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#define EXAMPLE_HOST "localhost"
#define EXAMPLE_USER "root"
#define EXAMPLE_PASS ""
#define EXAMPLE_DB "world"
using namespace std;
using namespace sql::mysql;
int main(int argc, const char **argv)
{
string url(argc >= 2 ? argv[1] : EXAMPLE_HOST);
const string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
const string database(argc >= 5 ? argv[4] : EXAMPLE_DB);
cout << "Connector/C++ tutorial framework..." << endl;
cout << endl;
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
driver = sql::mysql::get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "user", "password");
stmt = con->createStatement();
stmt->execute("USE " EXAMPLE_DB);
stmt->execute("DROP TABLE IF EXISTS test");
stmt->execute("CREATE TABLE test(id INT, label CHAR(1))");
stmt->execute("INSERT INTO test(id, label) VALUES (1, 'a')");
delete stmt;
delete con;
} catch (sql::SQLException &e) {
/*
The MySQL Connector/C++ throws three different exceptions:
- sql::MethodNotImplementedException (derived from sql::SQLException)
- sql::InvalidArgumentException (derived from sql::SQLException)
- sql::SQLException (derived from std::runtime_error)
*/
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
/* Use what() (derived from std::runtime_error) to fetch the error message */
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
return EXIT_FAILURE;
}
cout << "Done." << endl;
return EXIT_SUCCESS;
}
###END hello.cpp###
###BEGIN Make File###
SRCS := hello.cpp
OBJS := $(SRCS:.cpp=.o)
CXXFLAGS := -Wall -pedantic
INCPATHS := -I/home/user/mysql-connector/include/
LIBPATHS := -L/home/user/mysql-connector/lib/ -L/home/user/mysql-connector-c/lib/
LIBS := -static -lmysqlclient -mysqlcppconn-static
EXE := MyExecutable
$(EXE): $(OBJS)
$(CXX) $(OBJS) $(LIBPATHS) $(LIBS) -o $#
.cpp.o:
$(CXX) $(CXXFLAGS) $(INCPATHS) -c $< -o $#
###End Makefile###
Your problem is here , get_driver_instance isn't a member of sql::mysql,so to fix this removing sql::mysql:: and it will work
Change this line
driver = sql::mysql::get_driver_instance();
to this
driver = get_driver_instance();
check out the examples here
Include : ??
#include "mysql_driver.h"
Finally I could successfully compile a program with C++ connector in Ubuntu 12.04 I have installed the connector using this command
'apt-get install libmysqlcppconn-dev'
Initially I faced the same problem with "undefined reference to `get_driver_instance' " to solve this I declare my driver instance variable of MySQL_Driver type. For ready reference this type is defined in mysql_driver.h file. Here is the code snippet I used in my program.
sql::mysql::MySQL_Driver *driver;
try {
driver = sql::mysql::get_driver_instance();
}
and I compiled the program with -l mysqlcppconn linker option
and don't forget to include this header
#include "mysql_driver.h"
Looks like that function is in the global namespace, don't prepend with sql::mysql::