2010-11-30 31 views
1

Je possède ce simple code inséré dans le fichier myfile.hpp dans un projet de la mine:éditeur de liens C de ne peut pas trouver référence aux fonctions locales

#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 

Je Compile en utilisant cette directive de compilation:

g ++ * .cpp

Dans main.cpp notez qu'il y a #include "myfile.hpp", donc il est compilé.

g ++ me dit ceci:

/tmp/ccY04BAx.o: En fonction CalculatePI(middleware::calculus::PerformanceEvalParams const&)': main.cpp:(.text+0x1edd): undefined reference to middleware :: calcul :: RACINE (Double) » main.cpp :(texte + 0x1f43):. Non définie référence à middleware::calculus::Log(double, double)' main.cpp:(.text+0x1f72): undefined reference to middleware :: calcul :: Exp (double, double) » collect2: ld retourné 1 sortie état

Quel est le problème? Merci

Répondre

4

Vos fonctions déclarations sont dans l'espace de noms middleware::calculus, vos fonctions définitions ne sont pas. Les déclarations using que vous avez ajoutées avant les implémentations ne sont d'aucune aide ici (et elles ne sont généralement pas recommandées dans un fichier d'en-tête), et ne signifient certainement pas que l'omission de l'espace de noms dans les définitions impliquera implicitement correspondre 'les déclarations.

+0

Oui, vous avez tout à fait raison ... cristal clair, je était pressé et ne pensais pas que c'était un fichier hpp ... merci :) – Andry

+0

+1: @Andry: Il y a deux problèmes, le premier est que vous ne devriez jamais utiliser le 'using namespace' dans un en-tête, mais le problème principal n'est pas cela, mais le fait que, après 'using namespace middleware :: calculus; Une fonction 'Exp' (pour donner un exemple) définira' :: Exp', et non ':: middleware :: calculus :: Exp' même si la dernière a été déclarée plus tôt. C'est une bonne raison d'ouvrir toujours des espaces de noms lors de la définition des éléments, même si dans le cas de fonctions membres, le compilateur sera capable de trouver le bon type pour vous avec 'using namespace'. –

2
using namespace middleware::calculus; 
PIType CalculatePI(const PerformanceEvalParams& pep) 

Cela ne définit pas la fonction CalculatePI que vous avez déclaré précédemment à l'intérieur de l'espace de noms middleware::calculus. Cela déclare et définit une nouvelle fonction dans l'espace de noms global.

Soit vous devez qualifier le nom de la fonction dans la définition:

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

ou placer la définition dans l'espace:

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