首页 > 解决方案 > 在 RHEL 服务器中编译 C 文件时出错

问题描述

$ gcc -c exsystem.c
    In file included from exsystem1.c:39:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/include/varargs.h:4:2: error: #error "GCC no longer implements <varargs.h>."
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/include/varargs.h:5:2: error: #error "Revise your code to use <stdarg.h>."
exsystem1.c: In function âex_fprintfâ:
exsystem1.c:118: error: expected declaration specifiers before âva_dclâ
exsystem1.c:152: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before â{â token
exsystem1.c:174: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before â{â token
exsystem1.c:194: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before â{â token
exsystem1.c:216: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before â{â token
exsystem1.c:237: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before â{â token
exsystem1.c:261: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before âva_dclâ
exsystem1.c:293: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before â{â token
exsystem1.c:312: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before â{â token
exsystem1.c:336: error: expected â=â, â,â, â;â, âasmâ or â__attribute__â before âva_dclâ
exsystem1.c:364: error: expected â{â at end of input

这些是我在运行此代码时得到的错误 下面是有错误的代码片段: 有人可以帮助我根据 stdarg.h 新实现重写此代码。

void ex_fprintf( va_alist )
va_dcl
{
   va_list   args;
   FILE    * fp;
   char    * fmt;
   va_start( args );
   fp = va_arg( args, FILE * );
   fmt = va_arg( args, char * );
   if ( vfprintf( fp, fmt, args ) == EOF )
   {
      va_end( args );
      perror( "fprintf" );
      Raise( Ex_fprintf );
   }
   va_end( args );
   return;

}
void ex_printf( va_alist )
va_dcl
{
   va_list   args;
   char    * fmt;
   va_start( args );
   fmt = va_arg( args, char * );
   if ( vprintf( fmt, args ) == EOF )
   {
      va_end( args );
      perror( "printf" );
      Raise( Ex_printf );
   }
   va_end( args );
   return;

}

标签: cgccvariadic-functions

解决方案


语法类似,但主要区别在于stdarg在遍历堆栈上的参数时需要至少一个命名参数作为停止位置。

请参阅此链接,其中举例说明:http ://systemmanager.ru/svcsunix.en/extfile/portapps/stdargvsvarargs.htm


标准参数与可变参数

国际标准组织/美国标准协会 (ISO/ANSI) C 标准并没有与varargs.h中的历史例程冲突,而是定义了一种处理变量参数列表的新机制 stdarg.h可变参数机制对列表中的第一个参数使用一个神奇的名称 ( va_alist );stdarg使用最后一个必需的参数。这意味着stdarg必须至少有一个命名参数。

通常,您可以轻松地将varargs转换为stdarg,因为大多数具有可变参数列表的函数都具有已知的第一个参数类型。以下示例是一个使用可变参数机制的简单的错误打印函数:

#include <varargs.h>
printerror( va_alist );

void printerror (va_alist )
va_dcl
{
   va_list ap;
   char *fmt;
   va_start(ap);
   fmt = va_arg(ap, char *);
   vprintf(stderr, fmt, ap);
   va_end(ap);
}

因为该函数使用格式字符串作为其第一个参数,所以您可以轻松地将其用作已知参数:

#include <stdarg.h>
void printerror (char *fmt, ...)
{
   va_start(ap, fmt);
   vfprintf(stderr, fmt, ap);
   va_end(ap);
}

即使例程采用终止列表且没有固定参数,您也必须为第一个参数命名。例如,以下函数打印一组字符串,但第一个参数完全是人为的,是为了满足stdarg包的需要而创建的:

#include <stdarg.h>
pr_str(char *first, ...)
{
   char * current;
   va_list argp;
   va_start(argp,first);
   current = first;
   while (current != NULL){
   fputs(current,stdout);
   current = va_arg(argp, char *);
   }
   va_end(argp);
}

推荐阅读