以下程序om.c是通过xlC成功编译的,除了关于1506-196的警告!!
任何可以解释此类警告信息的人!?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char ch_sh[]="This is a program!!";
char k1[1200];
char *ls_sh=NULL;
size_t len=0;
FILE *om = open_memstream(&ls_sh, &len);
fprintf(om, " %32s", ch_sh);
if ( argv[1] != NULL )
{
fprintf(om, "%26s", argv[1]);
fclose(om);
sprintf(k1, "echo %s", ls_sh);
system(k1);
printf("\ndone message in program\n");
}
else
{
printf("Error: Empty input\n");
return 1;
}
free(ls_sh);
}
编译日志:
1. root@psph:/tmp#
root@psph:/tmp#
root@psph:/tmp#
root@psph:/tmp# xlC -o om om.c
"om.c", line 11.14: 1506-196 (W) Initialization between types "struct {...}*" and "int" is not allowed.
root@psph:/tmp#
root@psph:/tmp# xlC -qsrcmsg -o om om.c
11 | FILE *om = open_memstream(&ls_sh, &len);
.............a..............................
a - 1506-196 (W) Initialization between types "struct {...}*" and "int" is not allowed.
root@psph:/tmp# ./om data1
This is a program!! data1
done message in program
root@psph:/tmp#
root@psph:/tmp# xlC -qversion
IBM XL C/C++ for AIX, V11.1 (5724-X13)
Version: 11.01.0000.0000
Driver Version: 11.01(C/C++) Level: 100304
C Front End Version: 11.00(C/C++) Level: 100301
C++ Front End Version: 11.01(C/C++) Level: 100304
High-Level Optimizer Version: 11.01(C/C++) and 13.01(Fortran) Level: 100301
Low-Level Optimizer Version: 11.01(C/C++) and 13.01(Fortran) Level: 100304
root@psph:/tmp#
root@psph:/tmp#
root@psph:/tmp#
这就是全部!
答案 0 :(得分:2)
警告表示您正在影响指针的int值,这通常是由无效级别错误引起的。 open_memstream
不是标准C而是POSIX。
在这里,很可能对于xlC,open_memstream
中没有声明stdio.h
。然后编译器假定它应该是一个返回int的函数,因此警告。你应该让那个人(man open_memstream
)知道它所声明的包含文件,并将其包含在你的来源中。
答案 1 :(得分:1)
你收到警告:
Initialization between types "struct {...}*" and "int" is not allowed.
在这一行:
FILE *om = open_memstream(&ls_sh, &len);
第一个问题:open_memstream
不是标准的C库函数。它由某些版本的POSIX定义。我的Linux系统上的手册页(Ubuntu 16.10)说:
遵守 POSIX.1-2008。这些功能未在POSIX.1-2001中指定,并且在其他系统上不能广泛使用。
您可能正在尝试编译为另一个系统编写的代码(在另一个系统上提供open_memstream
的系统(一个不提供open_memstream
的系统)。或者它可能在您的系统上可用,但是你还没有提供使它可见所需的任何咒语。禁止使用符合标准的ISO C实现来定义标准头文件中除C标准定义的函数之外的函数(除非它们使用保留名称,这里不适用) ),但通常有一种方法可以请求符合POSIX而不仅仅是ISO C.如果是这种情况,系统上的手册页应该告诉你需要做什么:man open_memstream
。你可能需要定义一个宏或将命令行参数传递给编译器。
(如果所有特定于POSIX的函数都在单独的头文件中声明而不是共享C-standard行<stdio.h>
,那么所有这些都可能更简单,但是有历史原因可以解释为什么没有这样做。)< / p>
第二个问题:你也问过为什么你只会收到警告。在1999年ISO C标准之前,调用未声明的函数是合法的。编译器将创建一个隐式声明,假设该函数接受您传递的任何参数并返回类型int
的结果。如果实际函数与该假设不匹配,则行为未定义。 1999标准删除了这个“隐式int
”规则,调用未声明的函数约束违规。但编译器不需要拒绝违反此规则的代码;打印警告并继续编译是有效的。这意味着您应该认真对待C编译器非常的所有警告。
(如果您的系统没有open_memstream
,您可能会寻找fmemopen
,它看起来很相似。它也是由POSIX而不是ISO C定义的,所以同样的注意事项也适用。 )
更新:
由于您使用的是xlC
,我认为您使用的是AIX系统。这是man page for open_memstream
on AIX。
我看到没有关于启用ISO C未定义的符号的说明。手册页包含一个示例。这是一个精简版本,应该编译出错误:
#include <stdio.h>
int main(void) {
char *buf;
size_t len;
FILE *f = open_memstream(&buf, &len);
}
请尝试编译此示例。如果您收到关于open_memstream
的投诉,很可能您正在使用某些限制性命令行选项(尝试仅使用xlc c.c
进行编译)或您已经攻击了stdio.h
xlC
1}}。如果是后者,请将该头文件恢复为其原始内容。如果您没有保存原始备份,那么真的需要停止搞乱您的系统。
另外,如果我没记错的话,xlc
是C ++编译器; C编译器是SQL:
SELECT * FROM persDetails p
INNER JOIN level q
ON p.levelId = q.id AND q.level = 1
WHERE date = (SELECT max(date) from persDetails)
LINQ:
var result = from p in persDetails
join q in level on p.levelId equals q.level
where q.level = 1
join r in (from n in persDetails group n by n.departmentId into g select new { maxDate = g.Max(t => t.date)})
on p.date equals r.maxDate
select p;
。
答案 2 :(得分:0)
发布的代码存在一些问题。
应始终检查参数argc
以确保命令行参数实际存在。编译器输出有关未使用参数的警告
对open_memstream()
的调用应检查返回值(!= NULL),如果为NULL,则调用perror()
,以便将正确的错误消息传递给stderr
,包括系统认为呼叫失败的原因的文本。
因此,除了不使用传递的参数argc
而不检查open_memstream()
的返回值之外,程序编译并运行没有任何问题。
请注意,可以通过将以下内容作为argc
正文中的第一个语句来修复有关main()
的警告:
(void)argc;
此外,包含未使用这些内容的头文件是一种糟糕的编程习惯。 I.E.删除此声明:
#include <unistd.h>
然而,您的问题的根源是xlC编译器有关于数组初始化的错误。这在以下讨论:https://stat.ethz.ch/pipermail/r-sig-mac/2003-October/001009.html
答案 3 :(得分:-1)
最后我必须在int main之前手动添加以下声明,然后完美编译!!
FILE *open_memstream(char **, size_t *);
所以Jean-François的解决方案是正确的,但是为什么这只会导致这样的警告而不影响最终的编译和运行!?