C ++ компоновщик не может найти ссылку на локальные функции - PullRequest
1 голос
/ 30 ноября 2010

У меня есть этот простой код, вставленный в файл myfile.hpp внутри моего проекта:

#ifndef _PERFORMANCE_INDEX_HPP_
#define _PERFORMANCE_INDEX_HPP_

#include <boost/math/special_functions/powm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/sqrt1pm1.hpp>

//-----------------------------------------------------------------------------
// Enum, struct, aliases
namespace middleware {
namespace calculus {
/*!
 * Parameters needed for calculating PI.
 */
typedef struct {
    double eval_cpu_mhz; /* CPU MHz */
    double eval_ram_mb; /* RAM in MegaBytes */
    unsigned int eval_core_num; /* Number of cores per processor */
    unsigned int eval_cpu_num; /* Number of processors */
    unsigned int eval_hops; /* INET hop distance */
    double eval_bandwidth; /* Bandwidth in KBit/s */
    unsigned int eval_load; /* Number of tasks in queue in worker */
} PerformanceEvalParams;
/*!
 * PI type.
 */
typedef double PIType;
}
}
//-----------------------------------------------------------------------------
// Constants
namespace middleware {
namespace calculus {
const double kPerformanceEvalBeta = 3.0;
const double kPerformanceEvalDelta = 1.0;
const double kPerformanceEvalG = 1.60;
const double kPerformanceEvalH = 1.014;
const double kPerformanceEvalR = 512;
}
}
//-----------------------------------------------------------------------------
// Functions declarations
namespace middleware {
namespace calculus {
/*!
 * Used to calculate log in a given base.
 */
double Log(double base, double arg);
/*!
 * Used to calculate sqrt.
 */
double Sqrt(double arg);
/*!
 * Used to calculate exp by a given base.
 */
double Exp(double base, double arg);
/*!
 * Used for calculate PI
 */
PIType CalulatePI(const PerformanceEvalParams& pep);
}
}
//-----------------------------------------------------------------------------
// Functions implementations
using namespace middleware::calculus;
PIType CalculatePI(const PerformanceEvalParams& pep) {
    double N = -1, S = -1, C = -1; /* Parts */
    double PI = -1; /* Final result */
    N = (double)(kPerformanceEvalBeta * pep.eval_bandwidth);
    N = (double)(N / (double)((kPerformanceEvalDelta * (pep.eval_hops + 1))));
    N = (double)(Sqrt(N));
    S = (double)(pep.eval_cpu_mhz * pep.eval_cpu_num);
    S = (double)(S / ((double)(pep.eval_load + 1)));
    C = Log(kPerformanceEvalG, pep.eval_core_num);
    C = (double)(C + 1);
    C = (double)((double)1 + Exp(kPerformanceEvalH, -(pep.eval_ram_mb - 512)));
    PI = (double)(N * S * C);
    return PI;
}
double Log(double base, double arg) {
    // Boost Log returns boost::math::log1p(x) = log(e, x + 1)
    double res = (double)(boost::math::log1p(arg - 1));
    // Base conversion: log(new, y) = log(old, y) / log(old, new)
    // Then ==> log(base, arg) = log(e, arg) / log(e, base)
    res = (double)(res / boost::math::log1p(base));
    return res;
}
double Sqrt(double arg) {
    // Boost Sqrt returns boost::math::sqrt1pm1(x) = sqrt(1 + x) - 1
    double res = (double)(boost::math::sqrt1pm1(arg - 1));
    res = (double)(res + 1);
    return res;
}
double Exp(double base, double arg) {
    // Boost Pow returns boost::math::powm1(x, y) = x^y - 1
    double res = (double)(boost::math::powm1(base, arg));
    res = (double)(res + 1);
    return res;
}

#endif

Я компилирую, используя эту директиву компиляции:

g ++ * .cpp

В main.cpp обратите внимание, что есть #include "myfile.hpp", поэтому он компилируется.

g ++ говорит мне об этом:

/tmp / ccY04BAx.o: в функции CalculatePI(middleware::calculus::PerformanceEvalParams const&)': main.cpp:(.text+0x1edd): undefined reference to middleware :: calculus :: Sqrt (double) 'main.cpp :(. text + 0x1f43): неопределенная ссылка на middleware::calculus::Log(double, double)' main.cpp:(.text+0x1f72): undefined reference to middleware :: calculus :: Exp (double, double) 'collect2: ld вернул 1 статус выхода

В чем проблема?Спасибо

Ответы [ 2 ]

4 голосов
/ 30 ноября 2010

Ваши функции объявления находятся в пространстве имен middleware::calculus, ваши функции определения не являются.

Объявления using, которые вы добавили перед реализациями, здесь не помогают (и, кстати, обычно не рекомендуется в заголовочном файле), и, конечно же, не означают, что пропуск пространства имен в определениях неявно «сопоставить» объявления.

2 голосов
/ 30 ноября 2010
using namespace middleware::calculus;
PIType CalculatePI(const PerformanceEvalParams& pep)

Это не определяет функцию CalculatePI, которую вы ранее объявили внутри пространства имен middleware::calculus. Это объявляет и определяет новую функцию в глобальном пространстве имен.

Вам либо нужно указать имя функции в определении:

using namespace middleware::calculus;
PIType middleware::calculus::CalculatePI(const PerformanceEvalParams& pep) { 
    /* ... */ 
}

или поместите определение в пространство имен:

namespace middleware {
    namespace calculus {
        PIType CalculatePI(const PerformanceEvalParams& pep) { 
            /* ... */ 
        }
    }
}
...