2013-01-17 86 views
3

在C++中,main可以由函數指針定義嗎?例如:通過函數指針定義「main」

int f(int, char**) { 
    return 0; 
} 

int (*main)(int, char**) = &f; 

此代碼編譯和鏈接正確,但在運行時觸發分段錯誤。我相信這可能是因爲它試圖執行函數指針的值作爲代碼。另外,如果它在純C++中是不可能的,那麼它是否可以通過gcc的非標準特性(可能以某種方式改變導出的符號的類型)來實現。

最後,如果使用gcc指令無法實現,可以使用自定義鏈接腳本來完成嗎?

+2

爲什麼你需要這樣的修改?也許問題可以用較少的努力解決? – Spook

+0

這不是完全實用的,它主要是出於興趣。我想到的應用程序涉及模板。 – jleahy

+4

爲什麼你用'C'和'C++'標記這個,並且在實際問題中從來不問'C'?你爲什麼要弄亂函數指針?你爲什麼討厭'主'? *爲什麼?!* – stefan

回答

4

我相信你試圖做的事情在C++中是不可能的。我能想到的最簡單的方法是簡單地調用f在主:

int f(int, char**) { 
    return 0; 
} 

int main(int argc, char** argv) { 
    return f(argc, argv); 
} 

我也無法想象這樣一個場景,上述方案不會做。

4

我無法想象爲什麼你會想要這個,但不是,它絕對不可能用普通的C++。

如果你真的需要這樣的東西,只需要使用一個函數指針作爲main中的第一個命令。

6

的C++標準第3.6.1/1說:

「A方案應包括一項全球功能稱爲主,這是該計劃的指定的開始」

這使得指針聲明是非法的。

+0

這絕對回答了問題的第一部分。其他人依然存在。 – jleahy

+4

@jleahy:好吧,我想對其他問題的答案是「不要那樣做」。這不是合法的C++。 –

0

main 是C和C++中的關鍵字,並且 被覆蓋爲程序中的函數指針名稱。主要定義執行的入口點。因此,您的程序不具備該功能,並會覆蓋main它的段錯誤。

+11

不,主要不是關鍵字。標準的3.6.1.3段說'main'可以在其他地方使用。 – jrok

+0

@jrok,ok主不是關鍵字。我查了關鍵字部分。這似乎有點奇怪。如何將另一個函數定義爲「主函數」作爲程序的入口點? – Bort

+0

nvm我發現這個[回答](http://stackoverflow.com/questions/9677337/how-to-make-other-function-as-entry-point-other-than-main-in-c)。 – Bort

2

使用GCC,您可以使用-Wl選項將選項傳遞給鏈接器。然後,您可以使用鏈接器的--entry選項指定首先應調用哪個函數。

警告:這將不是做你期望的!程序的入口功能實際上是而不是main功能,但另一個功能是設置運行時環境,然後,然後調用你的main函數。

2

如果你在linux上,使用gcc的&,你可以將main聲明爲alias作爲任何其他函數。

例如下面的代碼工作(至少GCC,不與克測試++):

int f(int argc, char* argv[]) { 
    printf("hello world\n"); 
    return 0; 
} 

int main(int argc, char* argv[]) __attribute__ ((alias("f"))); 
0

另一個「髒」的方法是創建使用組件&作爲該函數的第一指令假功能,跳到f

下面是intel目標一個gcc特定代碼:

asm(".globl main");   // main is not static 
asm(".type main, @function"); // main is a 'function' 
asm("main: jmp f");   // main starts here. jump to `f` 

int g(){ //Some random function may be present in between "main" & "f"... 
    puts("hello universe"); 
} 

int f(int argc, char* argv[]) { 
    int i; 
    puts("hello world"); 
    printf("%d arguments given\n",argc - 1); 
    for(i=0;i<argc;i++) puts (argv[i]); 
    g(); 
    return 0; 
} 
+0

我一直以爲只是添加int main(int argc,char ** argv){return f();由於跳轉線程優化,}會編譯成相同的東西。 – jleahy

+0

嗯..這與Ivaylo的回答相同。在這個答案中的方法是明確的跳躍;如果優化未啓用。然而,我們可以在檢查程序集後確認...... :-) – anishsane

0

INT(*主)(INT,焦炭**)=&F;

看起來不正確。

什麼

int (*main)(int, char**) = f; 

+0

功能很有趣;函數名的值與'&function'(以及'* function'和其他變體)相同。 –