Storing pointers to static variables - c++

I've created a unit test framework for c++ which I want to port to C later and I've come across a problem where a unit test simply won't run. Unit tests are created in .cpp files and only one .cpp file should run all the tests.
To simplify a bit, this is how a test is typically created:
main.cpp
#define UNIT_TEST_IMPL // or whatever
#include "unit_test.hpp"
int main()
{
for(const auto& test : tests_queue)
test->run();
return 0;
}
unit_test.hpp
#pragma once
struct Base
{
protected:
Base() = delete;
Base(Base* ptr);
public:
virtual void run() = 0;
};
#if defined(UNIT_TEST_IMPL)
#include <vector>
std::vector<Base*> tests_queue;
Base::Base(Base* ptr)
{
tests_queue.push_back(ptr);
}
#endif
test.cpp
#include "unit_test.hpp"
#include <iostream>
struct Test : Base
{
Test()
: Base(this)
{}
void run() override
{
std::cout << "new test" << std::endl;
}
};
struct Test2 : Base
{
Test2()
: Base(this)
{}
void run() override
{
std::cout << "new test2" << std::endl;
}
};
static Test test;
static Test2 test2;
The question is: why is it not running the tests defined in test.cpp (if I create tests in the main.cpp file they run perfectly fine)? My guess is that the problem lies in the way I am storing Base pointers but I don't know.
The compiler is g++ 6.4.0

static-initialization-order-fiasco in action:
Initialization order of global across translation units is unspecified, so if test, test2 are instantiated before tests_queue, the later initialization would destroy the registration.
One possible correction:
#pragma once
struct Base
{
protected:
Base();
public:
virtual ~Base() = default;
virtual void run() = 0;
};
#if defined(UNIT_TEST_IMPL) // Should be defined only once.
#include <vector>
std::vector<Base*>& get_tests_queue()
{
static std::vector<Base*> tests_queue;
return tests_queue;
}
Base::Base()
{
get_tests_queue().push_back(this);
}
#endif
so your main.cpp would be:
#define UNIT_TEST_IMPL // or whatever
#include "unit_test.hpp"
int main()
{
for(const auto& test : get_tests_queue())
test->run();
}
Your unitTests would be unmodified:
#include "unit_test.hpp"
#include <iostream>
struct Test : Base
{
void run() override { std::cout << "new test" << std::endl; }
};
struct Test2 : Base
{
void run() override { std::cout << "new test2" << std::endl; }
};
static Test test;
static Test2 test2;
Demo

My bets go to some form of Static Initialization Fiasco
Not sure about it, but you cannot count on global variables (your Test1 and Test2 variables defined in test.cpp being initalized befor Main runs.
As a rule of thumb avoid global variables if you can (and in this case, you probably can).
But mainly, your program should not make any assumption on initialization order of global/static variables. Here you are assuming the two globals are initialized before main. Possibly, they are not

Related

Unexpected behaviour when using inheritance

I have a Base class, which is then inherited by Foo, and Foo is in turn inehrited by Bar.
Here is the header file base.h for my Base class:
#pragma once
class Base {
public:
void runExample();
private:
virtual void print();
};
And the implementation base.cpp:
#include "base.h"
void Base::runExample() {
print();
}
void Base::print() {};
Here is the header file foo.h for my Foo class:
#pragma once
#include "../base/base.h"
class Foo : public Base {
public:
Foo();
private:
void print();
const char* toPrint;
};
And the implementation foo.cpp:
#include "foo.h"
Foo::Foo() {
toPrint = "Hello Foo";
}
void Foo::print() {
std::cout << toPrint << std::endl;
}
Here is the header file bar.h for my Bar class:
#pragma once
#include "../foo/foo.h"
class Bar : public Foo {
public:
Bar();
private:
const char* toPrint; // "overrides" toPrint from parent class Foo?
};
And the implementation bar.cpp:
#include "bar.h"
Bar::Bar() {
toPrint = "Hello Bar";
}
And finally, my main function:
#include "../bar/bar.h"
int main() {
Bar bar = Bar();
bar.runExample();
}
So, I have this kind of relationship between the classes:
Bar is a Foo which is a Base.
What I was expecting to see in the output was "Hello Bar", but what I actually see is "Hello Foo".
If I "override" the print method declared in Foo in Bar to print toPrint then I get the expected result, however this seems to break the point of inheritance; i.e. why would I need to re-define the functionality when it's already defined.
What I am expecting is that when Bar.print() is invoked, it uses Foos implementation, but the actual field toPrint has been "replaced" with the value inside the Bar implementation.
I am very new to C++, and I'm coming from a Kotlin background. Forgive me if this is like C++ 101 basics, but I'm pretty confused as to why this is happening. Could anyone point me in the right direction?
In C++, data members cannot be "overridden" as you expect, and a reference to toPrint will not be dynamically bound to equally named data members in subclasses.
With
class Bar : public Foo {
...
const char* toPrint; // "overrides" toPrint from parent class Foo?
};
you introduce a member variable Bar::toPrint next to Foo::toPrint, which is inherited. The code
void Foo::print() {
std::cout << toPrint << std::endl;
}
will always stick to the toPrint-member in his scope, i.e. to Foo::toPrint.
The following code illustrates this behaviour:
struct Base {
const char* toPrint = "Base";
virtual void print() const { cout << toPrint << std::endl; }
};
struct Derived: public Base {
const char* toPrint = "Derived";
void printBoth() const { cout << "own:" << toPrint << "; inherited: " << Base::toPrint << std::endl; }
};
int main() {
Derived d;
cout << "call inherited method print:" << std::endl;
d.print();
cout << "call method printBoth, showing both data members:" << std::endl;
d.printBoth();
}
Output:
call inherited method print:
Base
call method printBoth, showing both data members:
own:Derived; inherited: Base

C++ independent static variable for each object inside a method

Consider the following code:
#include <iostream>
class CTest
{
public:
CTest() : c(0)
{}
void Method1()
{
c++;
std::cout<<"c: "<<c<<std::endl;
}
private:
int c;
};
int main()
{
CTest A,B,C;
A.Method1();
B.Method1();
C.Method1();
return 0;
}
c: 1
c: 1
c: 1
for each object of this type, the c value is different. To avoid name conflict, I am interested to put the c variable inside the function since Method1 is the only place where it is supposed to be used. My concern is how to make it independent for each different object. Is there any built-in C++ solution?
#include <iostream>
class CTest
{
public:
CTest()
{}
void Method1()
{
static int c=0;
c++;
std::cout<<"c: "<<c<<std::endl;
}
private:
};
int main()
{
CTest A,B,C;
A.Method1();
B.Method1();
C.Method1();
return 0;
}
c: 1
c: 2
c: 3
You could do this with templates,
template <typename int> class CTest
{
void Method1()
{
static int c = 0;
}
};
And instantiate CTest<1> A;, CTest<2> B; etc, taking care that you use a different int each time. That way, you get a different c per <n>, which is local to Method1. But this is quite contrived, will not work if you want to instantiate CTests dynamically, and I don't think I'd use it in production.
Perhaps an approach using the pImpl idiom would be better.
If this is just a naming issue, then you can just use different names:
class CTest
{
public:
void Method1()
{
int& c = unique_but_similar_to_something_else;
c++;
std::cout << "c: " << c <<std::endl;
}
private:
int unique_but_similar_to_something_else;
};
This allows your variable to have a correct name within class scope, but a more friendly name within method scope.
class CTest
{
public:
CTest() : MY__c(0)
{
}
void Method1()
{
int& c = MY__c; // now c is of different meaning and doesn't spoil the "c" we want to have no conflicts with...
c++;
std::cout << "c: " << c << std::endl;
}
private:
int MY__c;
};

Multiple classes with the same name causing vtable problems

I have an interesting problem that crept up and I was wondering why GCC/G++ doesn't catch this and throw some kind of error.
Apologies for how many files this takes, but I've reduced the problem as much as possible.
Interface.H
class BaseClass {
public:
virtual void hello() = 0;
};
void rememberClass(BaseClass* foo);
void callFunc();
Interface.C
#include "Interface.H"
namespace {
typedef void (BaseClass::*memfunptr)();
memfunptr func;
BaseClass* obj;
}
void rememberClass(BaseClass* foo) {
func = &BaseClass::hello;
obj = foo;
}
void callFunc() {
(obj->*func)();
}
Class1.H
class Class1 {
public:
Class1();
};
Class2.H
class Class2 {
public:
Class2();
};
Class1.C
#include "Interface.H"
#include "Class1.H"
#include <iostream>
class HelloClass : public BaseClass {
public:
HelloClass() {}
void hello() {
std::cout << "Calling Hello" << std::endl;
}
};
Class1::Class1() {
HelloClass* foo = new HelloClass();
rememberClass(foo);
}
Class2.C
#include "Interface.H"
#include "Class2.H"
#include <iostream>
class HelloClass : public BaseClass {
public:
HelloClass() {}
void hello() {
std::cout << "Calling Hello 2" << std::endl;
}
};
Class2::Class2() {
HelloClass* foo = new HelloClass();
rememberClass(foo);
}
main.C
#include "Class2.H"
#include "Interface.H"
int main(int argc, char** argv) {
Class2 a;
callFunc();
}
Output
g++ Class1.C Interface.C main.C Class2.C
./a.out
Calling Hello
As you can see above, Even though I am constructing a Class2, it prints the output from Class1. This is because the vtable for HelloClass in both the Class1 and Class2 have the same address for HelloClass::hello(), and it is the address of the function in Class1.C
I'm assuming that this is because when GCC is doing the linking, it sees vtables for classes with the same mangled names and just discards one of them. But should it warn about this? Or even cause an error. I have tried with -Wall and -Wextra but nothing is mentioned.
No, the standard explicitly allows the compiler to silently do the wrong thing in this case.
Explicitly, you are causing Undefined Behavior by having two conflicting definitions for the same decorated name in the same program.
It is called the ODR "One Definiton Rule".
Chapter 3.2.
Use explicit name for namespaces

Shared variable among classes c++

I have multiple classes that need to share a single instance of another class. Publicly it should be unknown that this class exists. Is it appropriate to do something like the following? (Was tested as written)
#include <iostream>
class hideme
{
private:
int a;
public:
void set(int b) { a = b; }
void add(int b) { a += b; }
int get() { return a; }
hideme() : a(0) { }
};
class HiddenWrapper
{
protected:
static hideme A;
};
hideme HiddenWrapper::A;
class addOne : public HiddenWrapper
{
public:
void add() { A.add(1); }
int get() { return A.get(); }
};
class addTwo : public HiddenWrapper
{
public:
void add() { A.add(2); }
int get() { return A.get(); }
};
int main()
{
addOne a;
addTwo b;
std::cout << "Initialized: " << a.get() << std::endl;
a.add();
std::cout << "Added one: " << a.get() << std::endl;
b.add();
std::cout << "Added two: " << b.get() << std::endl;
return 0;
}
For what it's worth, hideme is part of a library I'm attempting to design a facade around, and the other classes have members from the library that interact with the static hideme.
Additionally, if the header file written for HiddenWrapper has no corresponding source file, is that the best place to define its static member? With an include guard.
Is there any other method to solve this problem? As far as I could imagine (not terribly far) I could only solve it otherwise with friendship, which I am wary of.
You can prevent access to a class by not making it accessible outside the translation unit that uses it.
// public_header.h
class A {
void bar();
};
class B {
void foo();
}
// private_implementation.cpp
#include "public_header.h"
namespace {
class hidden { void baz() {} };
hidden h;
}
void A::bar() {
h.baz();
}
void B::foo() {
h.baz();
}
This class will be usable only by A::bar and B::foo. The type hidden and the variable h still technically have external linkage, but no other translation unit can say their names.
Sometimes it is a better idea to inject shared ressources (by reference or pointer) through the constructor (also known as composition instead of inheritance). This way gives you the ability to share or not (e.g. to have a thread-safe variant of your code which is not). See http://de.wikipedia.org/wiki/Inversion_of_Control principle for more info.
This implements a singleton around some other class and hides it from
users:
class hideme {};
// fwd declarations
class x;
// library internal
class S
{
S() = delete;
S(S const&) = delete;
void operator=(S const&) = delete;
private:
static hideme& getInstance()
{
static hideme instance;
return instance;
}
friend x;
};
// library classes
class x {
hideme& s;
public:
x() : s(S::getInstance()) {}
};
int main()
{
x x;
return 0;
}
This does not handle cases where you actually want the hideme
instance to be destroyed when no other object is using it anymore. For
that you need to get a little bit more inventive using reference
counting.
I also should say that I think this is a bad idea. Singletons almost
always are.
Generally, the best approach, if you have a variable in the main part, and want to share it with all classes.
For example, if class X makes a change on this var, the change happened to the var in the main as well: you can use EXTEND
************************ The main *********************
#include <iostream>
using namespace std;
#include "Game.hpp"
//0: not specified yet; 1:singlemode; 2:multiplayerMode
int playingMode = 0;
int main()
{
Game game;
game.Run();
std::cout<< playingMode << std::endl;
return 0;
}
*********************** Class X *****************
#include <iostream>
using namespace std;
extern int playingMode;
....
....
if(m_isSinglePressed)
{
playingMode = 1;
...
}
else if(m_isMultiPressed)
{
playingMode = 2;
...
}

c++ forward declaration

#include <iostream>
#include <cstring>
using namespace std;
class Obj;
class Test {
friend class Obj;
public:
Test()
{
}
~Test()
{
}
void foo()
{
//print();
//Obj::print();
//Obj x;
//x.print();
}
};
class Obj {
public:
void print()
{
cout << "print here" << endl;
}
};
int main()
{
Test test;
test.foo();
return 0;
}
Quick question,how can I call print the correct way in Test::foo() ?
You need to define the member function after the definition of Obj:
class Test {
public:
void foo();
};
class Obj {
public:
void print() { }
};
void Test::foo() {
Obj o;
o.print();
}
As mentioned by james you should define the member function after the definition of Obj. Also you are calling Obj::print, but print is not a static member function so you must call it on an instance of Obj not Obj itself.
If you really do want print to be a static member, declare it so.
class Obj {
public:
static void print(){ blah }
}
Also you do not need to make Obj a friend in order to access its public methods.
Also can OP please define "correct way", I was assuming you wanted it to be a static member function, james' answer is correct if you want one instance of Obj per instance of Test.
UPDATED
OP, as per your comment you must have the declaration of Obj along with print BEFORE using it within Test. This can be achieved in many ways:
move the entire class Obj defintion (and declaration) before Test
declare Obj's methods with its class definition and define them later.
declare Test like you have and Define Test as per James' post (after Obj).
The following works fine:
#include <iostream>
#include <cstring>
using namespace std;
class Obj {
public:
static void print()
{
cout << "print here" << endl;
}
};
class Test {
public:
Test()
{
}
~Test()
{
}
void foo()
{
Obj::print();
}
};
int main()
{
Test test;
test.foo();
return 0;
}
However it is always nicer (in my opinion) to separate declaration from definition for all but the most trivial of cases.