mercredi 28 janvier 2015

Clang OS X compiler balks on this code but it works fine on Linux

The following sample code works fine under linux using g++4.8.2. However, I get a strange linker error under MacOS X (Yosemite) using clang:



ld: internal error: atom not found in fruitIndex(__ZNSt3__112__hash_tableINS_17__hash_value_typeIKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEN15FRUIT_TUPLES4dataEEENS_22__unordered_map_hasherIS8_SB_NS9_8key_hashELb1EEENS_21__unordered_map_equalIS8_SB_NS9_9key_equalELb1EEENS5_ISB_EEE15__insert_uniqueIRKNS_4pairIS8_SA_EEEENSL_INS_15__hash_iteratorIPNS_11__hash_nodeISB_PvEEEEbEEOT_) for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Proces


The main.cpp file



#include "TupleFruits.hpp"

int main()
{
map_t fruitHash = InitializeFruitHash();

std::string fruit = "BANANA";

auto itr = fruitHash(fruit);
if (fruitHash.end() == itr)
{
std::cout << fruit << " not found in hash" << std::endl;

exit(1);
}
}


The FruitHash.cpp file:



#include "TupleFruits.hpp"

map_t InitializeSymbolHash()
{
static map_t m;

data dBANANA = {0, 0, 6, false};
data dGRAPEFRUIT = {1, 1, 6, false};
data dSTAWBERRY = {2, 2, 6, false};

m[BANANA] = dBANANA;
m[GRAPEFRUIT] = dGRAPEFRUIT;
m[STAWBERRY] = dSTAWBERRY;

return m;
}


The include file "HashData.hpp



#ifndef HASH_DATA_HPP
#define HASH_DATA_HPP

#include <string>
#include <unordered_map>
#include <cstring>
#include <iostream>
#include <tuple>

#include <boost/functional/hash.hpp>

typedef std::string fruit_key_t;

namespace HASH_TUPLES
{
struct key_hash : public std::unary_function<fruit_key_t, std::size_t>
{
std::size_t operator()(const fruit_key_t& k) const
{
std::hash<std::string> hash_fn;

return hash_fn(k);
}
};

struct key_equal : public std::binary_function<fruit_key_t, fruit_key_t, bool>
{
bool operator()(const fruit_key_t& v0, const fruit_key_t& v1) const
{
return (v0 == v1);
}
};

struct data
{
int row;
int column;
int precision;
bool isRipe;

inline bool operator ==(data d)
{
if (d.row == row && d.column == column)
return true;
else
return false;
}

friend std::ostream& operator << (std::ostream& os, const data& rhs) //Overloaded operator for '<<'
{ //for struct output
os << rhs.row << ", "
<< rhs.column;

return os;
}
};

typedef std::unordered_map<const fruit_key_t, data, key_hash, key_equal> map_t;
// ^ this is our custom hash

}

template<class T>
struct map_data_compare : public std::binary_function<typename T::value_type,
typename T::mapped_type,
bool>
{
public:
bool operator() (typename T::value_type &pair,
typename T::mapped_type i) const
{
return pair.second == i;
}
};

#endif


The include file "TupleFruits.hpp"



#ifndef TUPLESFRUITS_HPP
#define TUPLESFRUITS_HPP

#include <boost/interprocess/containers/string.hpp>

#include "HashData.hpp"

using namespace HASH_TUPLES;

map_t InitializeFruitHash();

static std::string BANANA = "banana";
static std::string GRAPEFRUIT = "grapefruit";
static std::string STRAWBERRY = "strawberry";

#endif

Aucun commentaire:

Enregistrer un commentaire