Xenon Xenon - 1 year ago 64
C++ Question

Symbol not showing up in object file

For some reason, one of the symbols defined in this file is not showing up in the object file:

/**
* || File: random.cc
* || Project: Shatter
* || Encoding: UTF-8
* || Author: ********
*
* Copyright (C) 2016 ********** *. ****
* All rights reserved.
* Use by explicit written permission only.
*
* Changelog:
* - Aug 24, 2016, 07:35:22 PM --- File was created by ********
*
*/

#include <shatter/random/random.h>

// @TODO: MOVE TO <config-build.h>
#define _M_FEATURE_ARC4RANDOM

#ifdef _M_FEATURE_ARC4RANDOM
#define RAND_SEED (arc4random())
#define RAND_IMPL (rand())
#else
#include <time.h>

#define RAND_SEED (time(NULL))
#define RAND_IMPL (rand())
#endif

#define _M_RANDOM_SET_SEED (srand( RAND_SEED ));

namespace shatter { namespace random {
static bool randomIsSeeded = false;

int random(int min, int max){
if(!randomIsSeeded){
_M_RANDOM_SET_SEED;
randomIsSeeded = true;
}

return (
(RAND_IMPL %
(max - min)
) + min
);
}

int d(int num, int sides){
int ttl = 0;
for(int di = 0;di < num;di++)
ttl += random(1, sides);

return ttl;
}

template <class T>
T randomFromSet(std::map<T, int> probs_keys){
int total_prob = 0;

/* HERE BE DRAGONS! */
typedef typename std::map<T, int>::iterator __local__iterator;

for(__local__iterator tprob_iter = probs_keys.begin();
tprob_iter != probs_keys.end();
++tprob_iter) {
total_prob += tprob_iter->last;
}

int target = random(0, total_prob);

for(__local__iterator targp_iter = probs_keys.begin();
targp_iter != probs_keys.end();
++targp_iter){
if(target < targp_iter->last){
return targp_iter->first;
}
}
}
} }

#undef _M_RANDOM_SET_SEED
#undef RAND_SEED
#undef RAND_IMPL


I compile the above file with
clang++ -g -std=c++11 -c
. For some reason, all of the symbols defined are put into the object file, except for
randomFromSet()
.

$ nm build/random/random.o
00000000000007a0 s EH_frame0
0000000000000050 T __ZN7shatter6random1dEii
0000000000000000 T __ZN7shatter6random6randomEii
0000000000000808 b __ZN7shatter6randomL14randomIsSeededE
U _arc4random
U _rand
U _srand


randomFromSet()
is called from the following function:

void Map::randomize(std::map<TileType, int> possibilities, int x, int y, int w, int h){
this->enforceBounds(&x, &y);
this->enforceBounds(&w, &h);

for(int yi = y;yi < h;yi++){
for(int xi = x;xi < w;xi++){
int tmp_type = shatter::random::randomFromSet<TileType>(possibilities);

this->tileMap[yi][xi]->type = (TileType) tmp_type;
}
}
}


Also: When compiling as a whole:

Undefined symbols for architecture x86_64:
"shatter::dungeon::TileType shatter::random::randomFromSet<shatter::dungeon::TileType>(std::__1::map<shatter::dungeon::TileType, int, std::__1::less<shatter::dungeon::TileType>, std::__1::allocator<std::__1::pair<shatter::dungeon::TileType const, int> > >)", referenced from:
shatter::dungeon::Map::randomize(std::__1::map<shatter::dungeon::TileType, int, std::__1::less<shatter::dungeon::TileType>, std::__1::allocator<std::__1::pair<shatter::dungeon::TileType const, int> > >, int, int, int, int) in map.o


I would greatly appreciate it if someone could enlighten me as to the reason why
randomFromSet
is not showing up in the object file.

Thanks in advance.

Answer Source

The function is a template and needs to have a caller before it exists.