I am trying to use pahole to analyze the memory layout of a C++ program which has some classes inside namespaces. pahole only lists classes in the global namespace. Is there an option to also list the other classes?
MWE:
namespace ns {
class Thing {
public:
int y;
Thing(int y) : y(y) { }
};
};
class Thong {
public:
int z;
Thong(int z) : z(z) { }
};
int main(void) {
ns::Thing x(1);
Thong a(2);
return x.y + a.z;
}
g++ -ggdb3 test.cpp
pahole --version; pahole a.out
v1.10
class Thong {
public:
int z; /* 0 4 */
void Thong(class Thong *, int);
/* size: 4, cachelines: 1, members: 1 */
/* last cacheline: 4 bytes */
};
After poking around in the source, I found out that the --show_private_classes option also prints classes defined in namespaces.
The namespace qualifier is dropped from the class name (ns1::foo and ns2::foo are both printed as just foo) but it's enough for my use case.
Related
This question already has an answer here:
error: no matching function for call to ‘Point::Point()
(1 answer)
Closed 7 months ago.
I developed two modules with separate implementation and interfaces.
These are the ones:
This is file Move.h:
#pragma once
#include "utils.h"
class Move {
private:
int x;
int y;
public:
Move(int x_inp, int y_inp);
char getX();
int getY();
};
And this is Move.cpp:
#include "Move.h"
Move::Move(int x_inp, int y_inp) {
int size = 10
this->x = x_inp;
this->y = y_inp;
};
int Move::getX() {
return this->x;
};
int Move::getY() {
return this->y;
}
This is the file Node.h:
#pragma once
#include "Move.h"
#include <vector>
class Node {
private:
Move move;
Node* parent;
std::vector <Node*> children;
public:
Node(Move inp_move, Node* parent_inp);
double value(const float EXPLORE_CONST);
void add_children(std::vector<Node*>);
};
#include "Node.cpp"
Node::Node(Move inp_move, Node* parent_inp) { // this is where compilation error rises.
this->move = inp_move;
this->parent = parent_inp;
}
void Node::add_children(std::vector<Node*> list_of_children) {
for (Node* item : list_of_children) {
this->children.push_back(item);
}
}
It always gives me the error that no default constructor exists for class "Move". I am really stuck and try to figure out the solution but didn't find the answer.
Can you guys help me please.
Thanks
you should try literally adding a default constructor to your "Move" class.
public:
Move() {}
//default constructor
Move(int x_inp, int y_inp);
char getX();
int getY();
};
´´´´
You need use member initializer lists:
Node::Node(Move inp_move, Node* parent_inp)
: move{inp_move}
, parent{parent_inp}
{
}
Or provide default constructor for Move as suggested in comment. IMO use of member initializer lists is better choice.
I want to create a struct that can be used to store 3D coordinates or a linear equation.
Here is the code:
struct myStruct {
union {
// coordinates (3d)
struct {
int x,y,z;
};
// linear equation (ax+b)
struct {
int a,b,x;
};
};
};
And I get the following error:
error: redeclaration of ‘int myStruct::<anonymous union>::<anonymous struct>::x’
I'm on linux mint 18.04, g++ (5.4.0), compile with --std=c++11.
I understand the problem. But have few questions.
I saw something related working on windows, why?
What is the best way to implement it so it works well on both (linux/win)?
Just give them names. This should be fine:
struct myStruct {
union {
struct coordinates { int x,y,z; };
struct linear_equation { int a,b,x; };
coordinates coord;
linear_equation lin_eq;
};
};
I also allowed myself to add some members to the union. However, the two structs have members of same types and quantity, so imho entering the trouble of using a union is questionable.
Just to complement the answer by user463035818. You can simplify your union a bit, by declaring the members directly, e.g.:
struct myStruct {
union {
// coordinates (3d)
struct {
int x,y,z;
} coord;
// linear equation (ax+b)
struct {
int a,b,x;
} lin_eq;
};
};
I've got multiple classes from multiple engineers which I am using and they have the same named structures in the classes. From this I get the error "'struct' type redefinition". How do I get around this?
Example:
// Eng1Class.h
#pragma once
struct Eng1And2SameName
{
unsigned int bottle;
};
class Eng1Class
{
public:
Eng1Class();
~Eng1Class();
};
.
// Eng2Class.h
#pragma once
struct Eng1And2SameName
{
float x, y;
};
class Eng2Class
{
public:
Eng2Class();
~Eng2Class();
};
.
// Main Program
#include "stdafx.h"
#include "Eng1Class.h"
#include "Eng2Class.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
Error: error C2011: 'Eng1And2SameName' : 'struct' type redefinition
According to this Compile error "'struct' type redefinition" although it's the first definition for it the #pragma once should fix the issues, but I still see the error. Any insights you can provide?
No, #pragma once prevents the header files from being included more than once - each is included once -> redefinition.
they have the same named structures in the classes
*header files
The're not defined inside the classes (nested), but they could be:
class Eng1Class
{
public:
struct Eng1And2SameName
{
unsigned int bottle;
};
Eng1Class();
~Eng1Class();
};
Or you could enclose the contents of those headers into two differently named namespaces.
Defining a namespace would help
For example as you said error with same struct definition in same namescope .
Reports error
You can do it by defining namesapce
#include<iostream>
using namespace std;
namespace Eng1 {
struct Eng1And2SameName
{
unsigned int bottle;
};
}
namespace Eng2
{
struct Eng1And2SameName
{
float x, y;
};
}
int main()
{
Eng1::Eng1And2SameName a;
Eng2::Eng1And2SameName b;
return 0;
}
Usually engineers working on the same product are coordinated somehow, at least they will use a common source code repository and a common build. Hence, conflicts should have come up earlier.
"uncoordinated" engineers may happen when they work on different products, and if so, each product could have its own namespace. Thereby, you can combine the products without having conflicts:
// in a header:
namespace Eng1Class {
struct Eng1And2SameName
{
unsigned int bottle;
};
class EngClass
{
public:
EngClass();
~EngClass();
};
}
// in the cpp-file
Eng1Class::EngClass::EngClass() {
cout << "hello, Class 1";
}
// in another (or even the same) header
namespace Eng2Class {
struct Eng1And2SameName
{
float x, y;
};
class EngClass
{
public:
EngClass();
~EngClass();
};
}
// in another (or even the same) cpp-file
Eng2Class::EngClass::EngClass() {
cout << "hello, Class 2";
}
Let's say I have a shared library called libfoo.so that also depends on another shared library called libbar.so. In libfoo.so, the only capability it provides is a class that stores two integers and can return the value of those two integers added together.
libfoo.so:
// Foo.hpp
class Foo
{
int x, y;
public:
Foo(int x, int y);
int add() const;
};
Now, in libbar.so, there are two classes: a Bar1 class that simply stores a string and a Bar2 class that stores an integer that is calculated by creating a Foo object and using the add() function to generate a new integer.
// Bar1.hpp
class Bar1
{
std::string str;
public:
Bar1(const std::string& str);
const std::string& getString() const;
};
// Bar2.hpp
#include "foo.hpp"
class Bar2
{
int z;
public:
Bar2(int x, int y);
int getInt() const;
};
Now, I want to write a program that uses Bar1. I do not care about Bar2. My very simple program looks like this:
// Test.cpp
#include <iostream>
#include "Bar1.hpp"
using namespace std;
int main()
{
Bar1 bar1("Hello");
cout << bar1.getString() << endl;
}
I compile this program like so:
g++ -c test.cpp -o test.o
g++ -o test test.o -lbar
The error that is generated is:
undefined reference to 'Foo::Foo(int, int)'
undefined reference to 'Foo::add() const'
This can be fixed by specifying '-lfoo' to the linker. However, I am now linking in a library that my binary will never use.
Is there a way to clean this up where the compiler understands that my binary does not care about resolving these symbols since I never use Bar2 anywhere in my program?
EDIT:
Adding the implementations of the classes. I didn't think that it mattered. Here they are:
// Foo.cpp
#include "Foo.hpp"
Foo::Foo(int new_x, int new_y)
{
x = new_x;
y = new_y;
}
int Foo::add() const
{
return x + y;
}
And here is Bar1.cpp:
// Bar1.cpp
#include "Bar1.hpp"
Bar1::Bar1(const std::string& the_str)
{
str = the_str;
}
const std::string& Bar1::getString() const
{
return str;
}
And here is Bar2.cpp:
// Bar2.cpp
#include "Bar2.hpp"
Bar2::Bar2(int x, int y)
{
Foo foo(x, y);
z = foo.add();
}
int Bar2::getInt() const
{
return z;
}
Note that it should be obvious that I am writing these classes like this purely for experimentation purposes. I am playing around with the linker and how a developer would link to libraries and use them.
where is foo.cpp and bar.cpp? you didn't implement classes foo and bar:
// foo.cpp
#include "Foo.hpp"
Foo::Foo(int X, int Y) : x(X), y(Y){}
int Foo::add()const{return x + y;}
// Bar1.cpp
#include "bar1.hpp"
Bar1::Bar1(const std::string& STR) : str(STR){}
const std::string& Bar1::getString() const{return str;}
// Bar2.cpp
#include "foo.hpp"
Bar2::Bar2(int X, int Y) : x(X), y(Y) {z = x + y;}
int Bar2::getInt() const{ return z;}
I new in C++ and I have difficulty to understand how to get my function with inheritance.
I have a Class that is link to another with inheritance, everything work except:
I cannot reach my superclass function.
Here's my class header : Point.h (I don't include the .cpp):
#ifndef Point_H
#define Point_H
#include <iostream>
class Point{
public:
Point();
void set_values (int , int);
void set_values (int , int , int );
void affichervaleurs();
int getX() const { return x; }
int getY() const { return y; }
private:
int x ;
int y ;
int z ;
};
#endif
Now My other class that try to access the function getX from Point.h :
The header : Carre.h
#ifndef Carre_H
#define Carre_H
#include "Point.h"
class Carre : public Point{
public:
Carre();
//Carre(int a , int b);
//Carre(int a, int b):Point(a,b) {};
//Carre(int a, int b, int c):Point(a, b, c) {};
//const Point &pp;
int Aire (){
};
void affichercar(){
};
};
#endif
Carre.cpp
#include <iostream>
using namespace std;
#include "Carre.h"
#include "Point.h"
Carre::Carre():Point(){
};
//Carre::Carre(int a, int b);
//const &pp;
int Aire (){
return (getX() * getY());
};
void affichercar(){
//cout << "Coordonnees X:" << x << endl;
};
It says that my GetX() is undeclared in my Carre.cpp .
Like I said I'm new in C++
Does someone know what I'm missing to make that code work. ?
Your definition is missing the class scope, which makes it a free function instead of a member.
It should be
int Carre::Aire (){
return getX() * getY();
};
In the .cpp file for Carre, the functions Aire and affichercar are global. Presumably you intended:
int Carre::Aire(){
return (getX() * getY());
};
For example.
Declaring function outside class body requires a class specifier:
int Carre::Aire () {
return (getX() * getY());
};
void Carre::affichercar() {
//...
}
Otherwise
int Aire () {
return (getX() * getY());
};
is just another function in global namespace that can exists simutaneously to Carre::Aire().
This is because you are not implementing the Aire function as being part of the Carre class.
Try changing
int Aire (){
to
int Carre::Aire (){
Also, you already have an implementation of the Aire method in the header file. You should either implement the function inline in the header file, or in the .cpp file, but not both. This also applies to your affichercar method.