xlC警告'类型之间的初始化'struct {...} *“和”int“是不允许的。

时间:2017-05-10 15:23:59

标签: c

以下程序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#

这就是全部!

4 个答案:

答案 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)

发布的代码存在一些问题。

  1. 应始终检查参数argc以确保命令行参数实际存在。编译器输出有关未使用参数的警告

  2. open_memstream()的调用应检查返回值(!= NULL),如果为NULL,则调用perror(),以便将正确的错误消息传递给stderr,包括系统认为呼叫失败的原因的文本。

  3. 因此,除了不使用传递的参数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的解决方案是正确的,但是为什么这只会导致这样的警告而不影响最终的编译和运行!?