可变参数在 CC 编译器上的 AIX 5.3 中不起作用
Variadic arguments don't work in AIX 5.3 on CC compiler
我目前有一堆调试宏(从 Zed 的书 Learn 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.3
和 CC for AIX version 6.0.0.0
。
形式:
#define debug(M, s ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ## s)
with s ...
不是 C,而是 C 的 GNU 扩展。参见 gcc documentation 声明:
If your macro is complicated, you may want a more descriptive name for the variable argument than VA_ARGS. CPP permits this, as an extension. You may write an argument name immediately before the ‘...’; that name is used for the variable argument. The eprintf macro above could be written
#define eprintf(args...) fprintf (stderr, args)
using this extension.
debug
宏的正确 C 形式是:
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__,
__LINE__, __VA_ARGS__)
您的代码——原始版本或使用非标准扩展的编辑版本,请参阅 ouah 的回答——在 AIX 6.1 上使用 XL C/C++ 编译对我来说很好v11.1.
您声明您的编译器是 CC for AIX version 6.0.0.0
。如果那是指 "IBM VisualAge C++ Professional for AIX, V6.0",则该版本是 announced in 2002,即不是真正最新的...
可变参数宏在 1999 年才包含在标准中,因此您的编译器版本很可能还不支持它们。
我目前有一堆调试宏(从 Zed 的书 Learn 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.3
和 CC for AIX version 6.0.0.0
。
形式:
#define debug(M, s ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ## s)
with s ...
不是 C,而是 C 的 GNU 扩展。参见 gcc documentation 声明:
If your macro is complicated, you may want a more descriptive name for the variable argument than VA_ARGS. CPP permits this, as an extension. You may write an argument name immediately before the ‘...’; that name is used for the variable argument. The eprintf macro above could be written
#define eprintf(args...) fprintf (stderr, args)
using this extension.
debug
宏的正确 C 形式是:
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__,
__LINE__, __VA_ARGS__)
您的代码——原始版本或使用非标准扩展的编辑版本,请参阅 ouah 的回答——在 AIX 6.1 上使用 XL C/C++ 编译对我来说很好v11.1.
您声明您的编译器是 CC for AIX version 6.0.0.0
。如果那是指 "IBM VisualAge C++ Professional for AIX, V6.0",则该版本是 announced in 2002,即不是真正最新的...
可变参数宏在 1999 年才包含在标准中,因此您的编译器版本很可能还不支持它们。