[英]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.o
或libdog.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.