2015-05-10 105 views
-3

我應該將規範標誌編譯爲gcc。然後gcc抱怨沒有照顧到返回值。當我使用變量獲取返回值時,gcc再次發出抱怨:如何讓我的程序無需警告即可編譯?

$ gcc -pedantic -Wall -ansi -O4 miniShell.c 
miniShell.c: In function ‘cd’: 
miniShell.c:108:9: warning: variable ‘other_return’ set but not used [-Wunused-but-set-variable] 
    int other_return; 
     ^
miniShell.c:107:12: warning: variable ‘return_value’ set but not used [-Wunused-but-set-variable] 
    char * return_value; 
      ^

如何解決警告?我的程序如下。

#include <sys/stat.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <dirent.h> 
#include <errno.h> 
#include <stdarg.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

#define BUFFER_LEN 1024 
#define BUFFERSIZE 1024 


int mystrcmp(char const *, char const *); 


void err_syserr(char *fmt, ...) 
{ 
    int errnum = errno; 
    va_list args; 
    va_start(args, fmt); 
    vfprintf(stderr, fmt, args); 
    va_end(args); 
    if (errnum != 0) 
     fprintf(stderr, "(%d: %s)\n", errnum, strerror(errnum)); 
    exit(EXIT_FAILURE); 
} 
int main() { 
    char line[BUFFER_LEN]; 
    char* argv[100];   
    char* path= "/bin/";  
    char progpath[20];  
    int argc;    
    size_t length; 
    char *token; 
    int i=0; 
    int pid; 
    while(1) { 
    i = 0; 
     printf("miniShell>> ");      

     if(!fgets(line, BUFFER_LEN, stdin)) { 
      break;         
     } 
     length = strlen(line); 
     if (line[length - 1] == '\n') { 
      line[length - 1] = '\0'; 
     } 
     if(strcmp(line, "exit")==0) {   
      break; 
     } 


     token = strtok(line," "); 

     while(token!=NULL) { 
      argv[i]=token; 
      token = strtok(NULL," "); 
      i++; 
     } 
     argv[i]=NULL;      

     argc=i;       
     for(i=0; i<argc; i++) { 
      printf("%s\n", argv[i]);  
     } 
     strcpy(progpath, path);   
     strcat(progpath, argv[0]);    

     for(i=0; i<strlen(progpath); i++) { 
      if(progpath[i]=='\n') { 
       progpath[i]='\0'; 
      } 
     } 
     pid= fork();    

     if(pid==0) {    
      execvp(progpath,argv); 
      fprintf(stderr, "Child process could not do execvp\n"); 

     } else {     
      wait(NULL); 
      printf("Child exited\n"); 
     } 

    } 
return (0); 
} 

int mystrcmp(char const *p, char const *q) 
{ 
    int i = 0; 
    for(i = 0; q[i]; i++) 
    { 
     if(p[i] != q[i]) 
      return -1; 
    } 
    return 0; 
} 

int cd(char *pth) { 
    char path[BUFFERSIZE]; 
    char cwd[BUFFERSIZE]; 
    char * return_value; 
    int other_return; 
    strcpy(path,pth); 

    if(pth[0] != '/') 
    { 
     return_value = getcwd(cwd,sizeof(cwd)); 
     strcat(cwd,"/"); 
     strcat(cwd,path); 
     other_return = chdir(cwd); 
    } else { 
     other_return = chdir(pth); 
    } 
    printf("Spawned foreground process: %d\n", getpid()); 
    return 0; 
} 
+3

要麼使用這些變量,要麼刪除它們。 – Mat

+0

@Mat我沒有使用變量,但他們沒有得到警告,因爲gcc抱怨,如果我省略了返回值的變量。我不知道這個選項不會產生警告。 –

+2

好吧,然後使用它們。你打電話的功能可能會失敗。檢查失敗。 – Mat

回答

3

字裏行間,我猜你試圖解決原來的問題是沿線的一個警告:

warning: ignoring return value of ‘chdir’ 

而你試圖解決由返回值賦值給一個變量(其本身現在未被使用)。

getcwdchdir如果它們失敗都可以返回錯誤代碼,這是GCC警告你的返回值。如果你想正確地修復警告,你應該添加邏輯到你的代碼來檢測和處理這些錯誤情況。否則,您可能會繼續出現與您的假設不一致的狀態(例如,如果getcwd失敗並且使緩衝區處於不正確的初始化狀態,則可能處於意外目錄中)。

我以爲這可能是通過將函數調用的結果強制轉換爲void來重寫,但這不起作用(您仍然可以玩技巧,但它們會變得雜亂無章!)。爲warn_unused_result屬性的GCC文件說:

的warn_unused_result屬性導致,如果這個屬性的 主叫功能不使用其返回 值發出警告。這是地方爲函數不檢查的結果是要麼 一個安全問題,或者總是錯誤有用,

這表明你不希望找到一個警告解決方法,並且確實應該檢查返回錯誤條件的值。

如果你真的想這樣做,結果分配給你做了一個變量,然後添加一個單次使用的是可變的,轉換爲void:

int res = chdir (cwd); 
/* I promise I don't need to check this return value. */ 
(void) res; 
1

在您的代碼中實際存在2個錯誤。第一個可能導致你改變你的代碼,然後引起你現在詢問的警告。

我敢打賭你的第一個初始警告是關於chdir。由於文件說:

人的chdir(3):「成功完成後,應當返還0 否則,-1,應當歸還,當前的工作目錄 應保持不變,並且errno將被設置到 表示錯誤。「

,因爲它說,chdir可以返回一個錯誤代碼指出,如果出了什麼差錯,並引起第一初始警告由於你根本無視該值。

然後你改變了你的代碼和值分配給另一個變量,並得到:

警告:變量「other_return」設置,但不使用[-Wunused,但設置變量] INT other_return;

,您可以在此功能,你只設置一個值,該變量看,但實際上並不在以後使用它,這意味着你可以將其刪除:

int cd(char *pth) { 
char path[BUFFERSIZE]; 
char cwd[BUFFERSIZE]; 
char * return_value; 
int other_return; 
strcpy(path,pth); 

if(pth[0] != '/') 
{ 
    return_value = getcwd(cwd,sizeof(cwd)); 
    strcat(cwd,"/"); 
    strcat(cwd,path); 
    other_return = chdir(cwd); 
} else { 
    other_return = chdir(pth); 
} 
printf("Spawned foreground process: %d\n", getpid()); 
return 0; 
} 

return_value同樣的事情。你可以直接刪除它們,因爲它們沒有被使用。

如果你想避免第一初始警告你總是可以做這樣的事情:

int res = chdir (cwd); 
(void) res; 

這是你做的編譯器,一切都很好的保證,他可以忽略警告。

+1

'man chdir(3)':「成功完成後返回0,否則返回-1,當前工作目錄保持不變,並且應設置errno來指示錯誤。 – usr2564301

1

其他用戶已經回答了你如何可以通過固定代碼擺脫的警告,但只是供參考:如果你想「忽略」的警告,旗編譯:

-Wno-unused-but-set-variable 

編譯器通常給你的結束標記警告(在你的情況下,它是--Wunused但設置變量)。要忽略它,只需將-W更改爲-Wno-

希望這有助於!