簡體   English   中英

extern錯誤-未定義引用

[英]error with extern - undefined reference to

我正在嘗試編譯我的代碼,但是當我這樣做時,它發生了:

In function `main':
/home/emilio/CB/QAP/main.cpp|42|undefined reference to `start_timers()'
/home/emilio/CB/QAP/main.cpp|45|undefined reference to `elapsed_time()'

我有“ timer.c”和“ timer.h”作為測量時間的外部函數。

計時器

#include <stdio.h>
#include <time.h>
#include "timer.h"


clock_t start_time;
double elapsed;

void start_timers(){
    start_time = clock();
}

double elapsed_time( type )
TIMER_TYPE type;

{
    elapsed = clock()- start_time;
    return elapsed / CLOCKS_PER_SEC;
}

計時器

extern clock_t start_time;
extern double elapsed;

int time_expired();
void start_timers();
double elapsed_time();

typedef enum type_timer {REAL, VIRTUAL} TIMER_TYPE;

main.cpp

#include "timer.h"
...
        double time;

        start_timers();
            launch_algorithm();;
        time = elapsed_time();
 ...

我該如何解決? 謝謝!

您正在混合使用C和C ++。 要在C ++文件中使用C語言,您必須像這樣包裝標頭

#ifdef __cplusplus
extern "C" 
{
#endif
    extern clock_t start_time;
    extern double elapsed;

    int time_expired();
    void start_timers();
    double elapsed_time();

    typedef enum type_timer {REAL, VIRTUAL} TIMER_TYPE;
#ifdef __cplusplus
}
#endif

我不確定這將如何與您的函數一起使用,因為您尚未將參數放在頭文件中的函數原型中。 通常,將它們添加為最佳做法,因此,如果仍然無法使用,請嘗試一下。

因此,您的理解似乎有一些漏洞,我將盡力填補空白...

主要問題是C和C ++的互操作性。

在C中,具有名為dog的函數,該函數接受一個int並返回_dog > void dog(int)將作為名稱類似_dog或類似名稱的符號被一致地轉換到目標文件中(但該符號名稱由平台和您正在使用的ABI)。

在C ++中,通過選擇采用函數重載的方式,還需要另一層抽象。.因此我們的函數void dog(int)可以命名為_void_dog_int或類似名稱(這稱為名稱重整)。

因此,如果您想在C ++程序中使用標准的C函數,則會有些陌生...

當您在C ++程序中編寫時

dog.h(某些庫的接口或只是C代碼)

void dog(int);

something.cpp

#include <doglib/dog.h>
void someMethod(void)
{
    dog(4);
}

編譯器會生成一個對象,該對象期望以c ++的方式命名dog( _void_dog_int ),但是鏈接器在dog.olibdog.a或任何目標文件中都找不到該符號(因為在目標文件中該符號為像_dog C程序一樣命名為_dog )。

因此,有一種方法可以告訴C ++編譯器該符號為C符號...構造為:

extern "C" void dog(int);

要么

extern "C"
{
     void dog(int);
     ...
}

這樣可以解決我們的問題,只不過它會使我們的C編譯器煩死了!

所以事情必須變得更加復雜。

#ifdef __cplusplus
extern "C" 
{
#endif
    void dog(int);
         ...

#ifdef __cplusplus
}
#endif

這些宏會擴展,因此在C ++中,它們具有extern“ C”,而在C中,它們沒有...

全局var的問題類似... C ++和std C對不合格的全局變量的處理方式有所不同...以支持名稱空間或某些C ++構造(我沒有專門研究過)

您需要對.c.h文件進行一些更改。 以及extern "C"后衛。

在timer.h中,函數聲明應為:

int time_expired(void);
void start_timers(void);
double elapsed_time(TIMER_TYPE type);

並且在timer.c文件中,這三行應該是相同的(減去分號)。

當前,您擁有所謂的“ K&R樣式”函數頭:

double elapsed_time( type )
TIMER_TYPE type;
{
    elapsed = clock()- start_time;
    return elapsed / CLOCKS_PER_SEC;
}

這種函數頭的問題是它不能形成原型 如果您弄錯了參數列表,則在大多數情況下編譯器不會抱怨。 您只是在運行時得到未定義的行為。

通過使用原型,編譯器將檢查函數是否傳遞了正確數量和類型的參數,並在必要時轉換參數。

可以想象,如果未對函數進行原型設計,則C ++編譯器的名稱處理錯誤。

注意 我在另一條評論中看到您說“我已將.c更改為.cpp”。 如果您打算將timer.cpp重命名為timer.c ,請不要這樣做! C和C ++是不同的語言。 您應該將其保留為timer.c 您的編譯設置應同時包括C和C ++編譯器。 C編譯器編譯C代碼,C ++編譯器編譯C ++代碼,其中帶有extern "C"指令的內容指示如何將二者粘合在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM