I have the following makefile to build the following few files.
FLAGS = -O3
release: main Collection
g++ -o main Collection.o main.o $(FLAGS)
main: main.cpp
g++ -c main.cpp -std=c++17 $(FLAGS)
Collection: Collection.cpp Collection.hpp
g++ -c Collection.cpp -std=c++17 $(FLAGS)
clean: main
rm -f main *.o
/// Collection.hpp
#include <unordered_map>
struct RecallAsIs {
static constexpr int val = 0;
};
template <int value>
struct RecallAdd {
static constexpr int val = value;
};
class Collection {
public:
Collection();
~Collection();
void Add(int key, int value);
template <class RecallPolicy = RecallAsIs>
int Get(int key) const;
private:
std::unordered_map<int, int> values_;
};
template <class RecallPolicy>
int Collection::Get(int key) const {
return Get(key) + RecallPolicy::val;
}
/// Collection.cpp
#include "Collection.hpp"
Collection::Collection() = default;
Collection::~Collection() = default;
void Collection::Add(int key, int value) { values_[key] = value; }
template <>
int Collection::Get<RecallAsIs>(int key) const {
return values_.at(key);
}
/// main.cpp
#include <iostream>
#include "Collection.hpp"
int main() {
Collection c;
c.Add(10, 12);
std::cout << c.Get(10) << std::endl;
return 0;
}
When turning off optimization, ie. setting FLAGS = -O0
, 12 is printed to the terminal. However, when setting FLAGS = -O3
, the program ends up hanging and I can't quite figure out why it's hanging.
My latest running theory is that in the general implementation of Collection::Get
in the hpp is inlined by the compiler when optimization is enabled and doesn't see the specialization thus calls itself recursively which leads to the program hanging. Is my analysis correct?