如何让我的程序在没有警告的情况下编译?
How can I make my program compile without warning?
我应该将带有规范标志的程序编译为 gcc。然后 gcc 抱怨 return 值没有被处理。当我使用变量获取 return 值时,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] = '[=11=]';
}
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]='[=11=]';
}
}
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;
}
您的代码中实际上有两处错误。第一个可能导致您更改代码,然后导致您现在询问的警告。
我敢打赌,第一个初始警告是关于 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."
正如它所说,chdir
可以 return 一个错误代码,说明是否出现任何问题,并且第一个初始警告是由于您忽略了该值而引起的。
然后您更改了代码并将值分配给另一个变量并得到:
warning: variable ‘other_return’ set but not used [-Wunused-but-set-variable]
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;
这是你向编译器保证一切正常,他可以忽略警告。
从字里行间看,我猜你试图解决的最初问题是一个警告:
warning: ignoring return value of ‘chdir’
并且您已尝试通过将 return 值分配给一个变量(它本身现在未被使用)来解决这个问题。
如果 getcwd
和 chdir
失败,它们都可以是 return 错误代码,这是 GCC 警告您的 return 值。如果您想正确修复警告,您应该在代码中添加逻辑来检测和处理这些错误情况。否则,您可能会继续使用与您的假设不一致的状态(例如,如果 getcwd
失败并使您的缓冲区处于错误初始化状态,您可能位于意外目录中)。
我曾认为这可以通过将函数调用的结果转换为 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,
这表明您不想为该警告寻找解决方法,实际上应该检查 return 值的错误情况。
如果你真的想这样做,像你所做的那样将结果分配给一个变量,然后添加对该变量的一次使用,转换为 void:
int res = chdir (cwd);
/* I promise I don't need to check this return value. */
(void) res;
其他用户已经回答了如何通过修复代码来消除警告,但仅供参考:如果你想 'ignore' 警告,使用标志编译:
-Wno-unused-but-set-variable
编译器通常会在警告结束时给你一个标记(在你的例子中,它是 -Wunused-but-set-variable)。要忽略它,只需将 -W 更改为 -Wno-
希望对您有所帮助!
我应该将带有规范标志的程序编译为 gcc。然后 gcc 抱怨 return 值没有被处理。当我使用变量获取 return 值时,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] = '[=11=]';
}
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]='[=11=]';
}
}
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;
}
您的代码中实际上有两处错误。第一个可能导致您更改代码,然后导致您现在询问的警告。
我敢打赌,第一个初始警告是关于 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."
正如它所说,chdir
可以 return 一个错误代码,说明是否出现任何问题,并且第一个初始警告是由于您忽略了该值而引起的。
然后您更改了代码并将值分配给另一个变量并得到:
warning: variable ‘other_return’ set but not used [-Wunused-but-set-variable] 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;
这是你向编译器保证一切正常,他可以忽略警告。
从字里行间看,我猜你试图解决的最初问题是一个警告:
warning: ignoring return value of ‘chdir’
并且您已尝试通过将 return 值分配给一个变量(它本身现在未被使用)来解决这个问题。
如果getcwd
和 chdir
失败,它们都可以是 return 错误代码,这是 GCC 警告您的 return 值。如果您想正确修复警告,您应该在代码中添加逻辑来检测和处理这些错误情况。否则,您可能会继续使用与您的假设不一致的状态(例如,如果 getcwd
失败并使您的缓冲区处于错误初始化状态,您可能位于意外目录中)。
我曾认为这可以通过将函数调用的结果转换为 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,
这表明您不想为该警告寻找解决方法,实际上应该检查 return 值的错误情况。
如果你真的想这样做,像你所做的那样将结果分配给一个变量,然后添加对该变量的一次使用,转换为 void:
int res = chdir (cwd);
/* I promise I don't need to check this return value. */
(void) res;
其他用户已经回答了如何通过修复代码来消除警告,但仅供参考:如果你想 'ignore' 警告,使用标志编译:
-Wno-unused-but-set-variable
编译器通常会在警告结束时给你一个标记(在你的例子中,它是 -Wunused-but-set-variable)。要忽略它,只需将 -W 更改为 -Wno-
希望对您有所帮助!