Skip to content
Advertisement

How can I make my program compile without warning?

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:

$ 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] = '';
        }
        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("%sn", argv[i]);      
        }
        strcpy(progpath, path);           
        strcat(progpath, argv[0]);            

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

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

        } else {                  
            wait(NULL);
            printf("Child exitedn");
        }

    }
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: %dn", getpid());
    return 0;
}

Advertisement

Answer

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).

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:

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,

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:

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