如何在没有警告的情况下编译程序?

时间:2021-08-23 00:14:36

I should compile my program with spec flags to gcc. Then gcc complained about return values not taken care of. WhenI use variables to take the return values then gcc complains again:

我应该用spec标志编译我的程序到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;
            ^

How can I resolve the warnings? My program is as follows.

我该如何解决警告?我的计划如下。

#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 个解决方案

#1


3  

Reading between the lines, I guess the original problem you were trying to solve was a warning along the lines of:

在线之间阅读,我想你试图解决的原始问题是一个警告:

 warning: ignoring return value of ‘chdir’

And you've tried to fix that by assigning the return value to a variable (which itself is now unused).

并且您已尝试通过将返回值分配给变量(其本身现在未使用)来解决此问题。

getcwd and chdir can both return error codes if they fail, which are the return values GCC is warning you about. If you want to fix the warning properly you should add logic to your code to detect and handle these error cases. Otherwise, you are potentially continuing with a state inconsistent with your assumptions (for example, you may be in an unexpected directory if getcwd failed and left your buffer in an incorrectly initialised state).

getcwd和chdir都可以返回错误代码,如果它们失败,这是GCC警告你的返回值。如果要正确修复警告,则应在代码中添加逻辑以检测和处理这些错误情况。否则,您可能会继续处理与您的假设不一致的状态(例如,如果getcwd失败并且您的缓冲区处于错误的初始化状态,则可能处于意外目录中)。

I had thought that this could be over-ridden by casting the result of the function call to void, but this does not work (you can still play tricks, but they get messy!). The GCC documentation for the warn_unused_result attribute says:

我曾经认为通过将函数调用的结果转换为void可能会过度使用,但这不起作用(你仍然可以玩弄技巧,但它们会变得混乱!)。 warn_unused_result属性的GCC文档说:

The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is useful for functions where not checking the result is either a security problem or always a bug,

如果具有此属性的函数的调用者不使用其返回值,则warn_unused_result属性会导致发出警告。这对于不检查结果是安全问题还是总是错误的函数很有用,

Which suggests that you don't want to find a workaround for the warning, and should really be checking the return value for error conditions.

这表明您不希望找到警告的解决方法,并且应该确实检查错误条件的返回值。

If you really want to do it, assign the result to a variable as you have done, then add a single use of that variable, cast to void:

如果您真的想这样做,请将结果分配给变量,然后添加该变量的一次使用,强制转换为void:

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

#2


1  

The other users have answered how you can get rid of the warning by fixing your code, but just for reference: If you want to 'ignore' the warnings, compile with the flag:

其他用户已经回答了如何通过修复代码来消除警告,但仅供参考:如果您想“忽略”警告,请使用标志进行编译:

-Wno-unused-but-set-variable

The compiler usually gives you a tag at the end of a warning (in your case, it's -Wunused-but-set-variable). To ignore it, just change the -W to a -Wno-

编译器通常会在警告结束时为您提供一个标记(在您的情况下,它是-Wunused-but-set-variable)。要忽略它,只需将-W更改为-Wno-

Hope this helps!

希望这可以帮助!

#3


1  

There are actually 2 things wrong here in your code. The first one probably caused you to change your code, which then caused the warning you are now asking about.

你的代码中实际上有两个错误。第一个可能导致您更改代码,然后导致您现在要求的警告。

I bet you the first initial warning was about chdir. As the documents say:

我打赌你的第一个初步警告是关于chdir。正如文件所说:

man chdir(3): "Upon successful completion, 0 shall be returned. Otherwise, -1 shall be returned, the current working directory shall remain unchanged, and errno shall be set to indicate the error."

man chdir(3):“成功完成后,返回0。否则,返回-1,当前工作目录应保持不变,并设置errno以指示错误。”

As it says, chdir can return an error code stating if anything went wrong and the first initial warning was caused due to the fact you simply ignored that value.

正如它所说,chdir可以返回一个错误代码,说明是否出现任何问题,并且第一个初始警告是由于您只是忽略该值而引起的。

Then you changed your code and assigned the value to another variable and got:

然后,您更改了代码并将值分配给另一个变量并得到:

warning: variable ‘other_return’ set but not used [-Wunused-but-set-variable] int other_return;

警告:变量'other_return'设置但未使用[-Wunused-but-set-variable] int other_return;

and you can see in this function that you are only setting a value to that variable but don't actually use it later which means you can delete it:

并且您可以在此函数中看到您只是为该变量设置了一个值,但是之后实际上并没有使用它,这意味着您可以将其删除:

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;
}

Same thing for return_value. You can simply delete them both since they are not in use.

return_value也是一样。你可以简单地删除它们,因为它们没有被使用。

In case you want to avoid the first initial warnings you can always do something like this:

如果您想避免第一次初始警告,您可以随时执行以下操作:

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

This is an assurance made by you to the compiler that everything is fine and he can ignore the warning.

这是您对编译器保证一切正常并且可以忽略警告的保证。

#1


3  

Reading between the lines, I guess the original problem you were trying to solve was a warning along the lines of:

在线之间阅读,我想你试图解决的原始问题是一个警告:

 warning: ignoring return value of ‘chdir’

And you've tried to fix that by assigning the return value to a variable (which itself is now unused).

并且您已尝试通过将返回值分配给变量(其本身现在未使用)来解决此问题。

getcwd and chdir can both return error codes if they fail, which are the return values GCC is warning you about. If you want to fix the warning properly you should add logic to your code to detect and handle these error cases. Otherwise, you are potentially continuing with a state inconsistent with your assumptions (for example, you may be in an unexpected directory if getcwd failed and left your buffer in an incorrectly initialised state).

getcwd和chdir都可以返回错误代码,如果它们失败,这是GCC警告你的返回值。如果要正确修复警告,则应在代码中添加逻辑以检测和处理这些错误情况。否则,您可能会继续处理与您的假设不一致的状态(例如,如果getcwd失败并且您的缓冲区处于错误的初始化状态,则可能处于意外目录中)。

I had thought that this could be over-ridden by casting the result of the function call to void, but this does not work (you can still play tricks, but they get messy!). The GCC documentation for the warn_unused_result attribute says:

我曾经认为通过将函数调用的结果转换为void可能会过度使用,但这不起作用(你仍然可以玩弄技巧,但它们会变得混乱!)。 warn_unused_result属性的GCC文档说:

The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is useful for functions where not checking the result is either a security problem or always a bug,

如果具有此属性的函数的调用者不使用其返回值,则warn_unused_result属性会导致发出警告。这对于不检查结果是安全问题还是总是错误的函数很有用,

Which suggests that you don't want to find a workaround for the warning, and should really be checking the return value for error conditions.

这表明您不希望找到警告的解决方法,并且应该确实检查错误条件的返回值。

If you really want to do it, assign the result to a variable as you have done, then add a single use of that variable, cast to void:

如果您真的想这样做,请将结果分配给变量,然后添加该变量的一次使用,强制转换为void:

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

#2


1  

The other users have answered how you can get rid of the warning by fixing your code, but just for reference: If you want to 'ignore' the warnings, compile with the flag:

其他用户已经回答了如何通过修复代码来消除警告,但仅供参考:如果您想“忽略”警告,请使用标志进行编译:

-Wno-unused-but-set-variable

The compiler usually gives you a tag at the end of a warning (in your case, it's -Wunused-but-set-variable). To ignore it, just change the -W to a -Wno-

编译器通常会在警告结束时为您提供一个标记(在您的情况下,它是-Wunused-but-set-variable)。要忽略它,只需将-W更改为-Wno-

Hope this helps!

希望这可以帮助!

#3


1  

There are actually 2 things wrong here in your code. The first one probably caused you to change your code, which then caused the warning you are now asking about.

你的代码中实际上有两个错误。第一个可能导致您更改代码,然后导致您现在要求的警告。

I bet you the first initial warning was about chdir. As the documents say:

我打赌你的第一个初步警告是关于chdir。正如文件所说:

man chdir(3): "Upon successful completion, 0 shall be returned. Otherwise, -1 shall be returned, the current working directory shall remain unchanged, and errno shall be set to indicate the error."

man chdir(3):“成功完成后,返回0。否则,返回-1,当前工作目录应保持不变,并设置errno以指示错误。”

As it says, chdir can return an error code stating if anything went wrong and the first initial warning was caused due to the fact you simply ignored that value.

正如它所说,chdir可以返回一个错误代码,说明是否出现任何问题,并且第一个初始警告是由于您只是忽略该值而引起的。

Then you changed your code and assigned the value to another variable and got:

然后,您更改了代码并将值分配给另一个变量并得到:

warning: variable ‘other_return’ set but not used [-Wunused-but-set-variable] int other_return;

警告:变量'other_return'设置但未使用[-Wunused-but-set-variable] int other_return;

and you can see in this function that you are only setting a value to that variable but don't actually use it later which means you can delete it:

并且您可以在此函数中看到您只是为该变量设置了一个值,但是之后实际上并没有使用它,这意味着您可以将其删除:

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;
}

Same thing for return_value. You can simply delete them both since they are not in use.

return_value也是一样。你可以简单地删除它们,因为它们没有被使用。

In case you want to avoid the first initial warnings you can always do something like this:

如果您想避免第一次初始警告,您可以随时执行以下操作:

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

This is an assurance made by you to the compiler that everything is fine and he can ignore the warning.

这是您对编译器保证一切正常并且可以忽略警告的保证。