今天在查看了HP-UNIX下/usr/include/iconv.h里面的头文件时,发现一段下面的代码:
#if defined(__ia64)
/* pragmas needed to support -B protected */
# pragma extern iconv_open, iconv, iconv_close
#endif /* __ia64 */
extern iconv_t iconv_open __((const char *, const char *));
extern size_t iconv __((iconv_t, char ** __restrict, size_t * __restrict, char ** __restrict, size_t * __restrict));
extern int iconv_close __((iconv_t));
当时觉得很奇怪:iconv_open后为什么有空格还接着两个下划线呢?查看了AIX下对应的头文件,而其声明却比较符号C标准。
开始以为pragma extern在做怪,随后以多个关键字google/baidu一下,没有任何发现。
于是有群里问了一下,有人提醒说是为了兼容K&R C ,但没有具体细说,后经另外一个群的提醒说是有可能为宏定义等。。以为是编译器加了一些自己的处理,于是自己写了一个测试的hello.c
#include <stdio.h>
#pragma extern add
int add__(int,int);
int add(int x,int y)
{
printf("add be called...\n");
return x+y;
}
int main(int argc,char *argv[])
{
printf("test ....\n");
printf("add call:%d\n",add(29,58));
return 0;
}
发现可以编译运行通过。但是要将声明改成int add __(int,int)就编译不过。
讨论之余,确定应是一种宏定义。于是想找着这个宏定义,在iconv.h中发现有一个/sys/stdsyms.h可疑,在/usr/include/sys/stdsyms.h中终于找到了相应的宏定义:
/* macros for simplifying prototype declarations */
#undef __
#if defined(_PROTOTYPES)
# define __(arg) arg
#else
# define __(arg) ()
#endif
看来的确是为了兼容K&R C。问题来龙去脉已明确,看来hp-unix的确有点儿不一样。
另注:hp-unix下,/usr/include/sys/stdsyms.h比较重要,里面有平台相关的内容,通过各个宏来定义平台之间的差异。