2016-04-28 62 views
3

這是原型execv我可以傳遞一個const char *數組給execv嗎?

int execv(const char *path, char *const argv[]); 

我可以通過作爲第二個參數的const char指針的數組?

這個例子程序給出了當USE_CAST未設置警告:

#include <unistd.h> 
int main(int argc, char *argv[]) 
{ 
    if (argc > 0) { 
     const char *exe_name = "/bin/echo", *message = "You ran"; 
     const char *exe_args[] = { exe_name, message, argv[0], NULL }; 
#ifdef USE_CAST 
    execv("/bin/echo", (char **) exe_args); 
#else 
    execv("/bin/echo", exe_args); 
#endif 
    } 
    return 0; 
} 

編譯時,GCC說,「從傳遞兼容的指針類型‘execv’的論點2:」如果我不使用投。

POSIX documentationexecv(中途理由部分),它看起來像第二個參數是爲了向後兼容一個char *const數組:

argv[]envp[]是常數包含的語句,以向未來的作者明確表示這些對象是完全不變的語言綁定。 ...不幸的是,第四列不能使用...

其中「第四列」是指const char* const[]

這個(char **)可以放心使用嗎?我應該創建一個char *數組並將其傳遞給execv而不是?

回答

1

我可以傳遞一個const char指針數組作爲第二個參數嗎?

那麼,你已經知道你可以施展才能這樣做。

從POSIX文檔execv(中途原理部分),它看起來像第二個參數是爲了向後兼容性char * const的數組:

我不會把它放在這些條款,但是,對選定的簽名有一個兼容性方面。您引用的部分解釋說,C沒有完全令人滿意的方式來表達const的程度 - POSIX要求execv()提供參數。 POSIX保證該函數不會更改argv中的指針或它們指向的字符串。

由於這種情況,我認爲按照您的建議去做argv指針並不合理,儘管我會在代碼中留下評論,解釋爲什麼這樣做是安全的。

在另一方面,你應該考慮乾脆離開const了你的數組聲明:

char *exe_name = "echo", *message = "You ran"; 
char *exe_args[] = { exe_name, message, argv[0], NULL }; 

或者,在簡單的例子,即使這會做:

char *exe_args[] = { "echo", message, argv[0], "You ran", NULL }; 

C字符串文字對應於char類型的數組,而不是const char,因此就C而言,這是完全合法的,即使實際嘗試修改這些字符串的內容可能會失敗。

在第三隻手,現代C具有數組文本,所以你甚至可以這樣做:

execv("/bin/echo", (char *[]) { "echo", "You ran ", argv[0], NULL }); 

在你甚至不必強制轉換(類似一個東西,最後一種情況就是一部分數組文字的語法)。

+0

不知何故,我認爲字符串文字是'const char'。我認爲,從我使用的變量中抽出「const」並不是那麼糟糕,儘管我開始認爲我誤解了常量的正確性,或者它在C中並不總是實際可行的。 – yellowantphil

+0

@anaranjada ,不過,標準規定它們是'char'類型的數組,儘管在實踐中它們可能是不可寫的。 GCC可以選擇使用'const char'數組來替代,以幫助您找到試圖寫入其中的地方 - 也許這正是您想要的。 (因爲這個原因,當你啓用該選項時'gcc'不合格。) –

+0

是的,我認爲GCC選項讓我失望。無論如何,我從代碼中刪除了一些'const'限定符,現在編譯時沒有警告。謝謝。 – yellowantphil

1

如果你只是拋棄const,那麼你不應該使用const開始。大多數(我敢說全部)編譯器會接受下面的代碼

char *exe_name = "/bin/echo"; 
char *message = "You ran"; 
char *exe_args[] = { exe_name, message, argv[0], NULL }; 
execv(exe_args[0], exe_args); 

如果不是迂腐正確夠你,那麼另一種選擇是

char exe_name[] = "/bin/echo"; 
char message[] = "You ran"; 
char *exe_args[] = { exe_name, message, argv[0], NULL }; 
execv(exe_args[0], exe_args); 

注意execv將會使副本的字符串(爲可執行文件創建argv數組),所以字符串實際上是否爲const並不重要。

+0

是的,你敢,至少如果你願意將你的陳述限制在* conforming *編譯器。根據標準,字符串字面值對應於類型爲(非''const')'char'的元素的靜態數組。因此,您甚至不需要使用中間變量來形成數組初始值設定項。 –

相關問題