Variadic参数在CC编译器

时间:2015-11-03 13:08:33

标签: c macros

我目前有一堆调试宏(从Zed的书中学习C The Hard Way),我试图在AIX上编译它们。宏:

#ifndef __dbg_h__
#define __dbg_h__

#include <stdio.h>
#include <errno.h>
#include <string.h>

#ifdef NDEBUG
#define debug(M, s ...)
#else
#define debug(M, s ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ## s)
#endif

#define clean_errno() (errno == 0 ? "None" : strerror(errno))


#define log_err(M, s ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ## s)

#define log_warn(M, s ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ## s)

#define log_info(M, s ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ## s)

#define check(A, M, s ...) if(!(A)) { log_err(M, ## s); errno=0; goto error; }

#define sentinel(M, s ...)  { log_err(M, ## s); errno=0; goto error; }

#define check_mem(A) check((A), "Out of memory.")

#define check_debug(A, M, s ...) if(!(A)) { debug(M, ## s); errno=0; goto error; }

#endif

当我编译导入这些宏的项目时,AIX CC编译器会使用此消息打印编译器错误,然后正常退出:

"src/dbg.h", line 13.19: 1506-211 (S) Parameter list must be empty, or consist of one or more identifiers separated by commas.

它将其中一个打印到项目中使用其中一个宏函数的每一行。

我已按照此article的建议尝试设置#pragma langlvl (stdc99)#pragma langlvl (extc99)但未成功。

我还写了一个小例子,看看我是否可以编译它,如下所示:

/* file "test.c" */
#include <stdio.h>

#define PRINTERROR(M, s...) fprintf(stderr, "ERROR MSG: " M "\n", ## s)

int main(void) {
  PRINTERROR("no args");
  PRINTERROR("with args: %s", "foo");
  return 0;
}

编译器发出以下消息:

"test.c", line 4.24: 1506-211 (S) Parameter list must be empty, or consist of one or more identifiers separated by commas.

我正在使用AIX 5.3CC for AIX version 6.0.0.0

2 个答案:

答案 0 :(得分:3)

您的代码 - 使用非标准扩展的原始版本或已编辑的代码,请参阅ouah的答案 - 使用XL C / C ++ v11.1在AIX 6.1上编译好。

您声明您的编译器是CC for AIX version 6.0.0.0。如果这意味着“IBM VisualAge C ++ Professional for AIX,V6.0”,那个版本是announced in 2002,即不是真的最新...

Variadic宏仅在1999年被包含在标准中,所以很可能你的编译器版本还不支持它们。

答案 1 :(得分:2)

表格:

#define debug(M, s ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ## s)
带有s ...

不是C而是C的GNU扩展。请参阅gcc documentation

  

如果您的宏很复杂,您可能需要一个比 VA_ARGS 更具描述性的变量参数名称。 CPP允许这作为扩展。您可以在'...'之前写一个参数名称;该名称用于变量参数。上面的eprintf宏可以写成

 #define eprintf(args...) fprintf (stderr, args)
  

使用此扩展程序。

debug宏的正确C表单是:

#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__,
         __LINE__, __VA_ARGS__)