【问题标题】:open_memstream warning "pointer from integer without a cast"open_memstream 警告“来自没有强制转换的整数的指针”
【发布时间】:2013-02-13 20:30:22
【问题描述】:

我正在使用 open_memstream 为嵌入式 linux 系统编写一些 C 代码,但我不明白为什么我会收到编译警告:assignment make pointer from integer without a cast

为了简单起见,我没有粘贴我所有的代码,而是通过here 中的小示例重现了这个问题:

#include <stdio.h>
#include <stdlib.h>

int
main (void)
{
    FILE *stream;
    char *buf;
    size_t len;
    off_t eob;

    stream = open_memstream (&buf, &len);
    if (stream == NULL)
        /* handle error */ ;
    fprintf (stream, "hello my world");
    fflush (stream);
    printf ("buf=%s, len=%zu\n", buf, len);
    eob = ftello(stream);
    fseeko (stream, 0, SEEK_SET);
    fprintf (stream, "good-bye");
    fseeko (stream, eob, SEEK_SET);
    fclose (stream);
    printf ("buf=%s, len=%zu\n", buf, len);
    free (buf);
    return 0;
}

代码有效,但编译器抱怨stream = open_memstream (&amp;buf, &amp;len);这一行

它在说什么整数?我们按照函数原型的要求传递了一个指向 size_t 的指针。

FILE *open_memstream(char **bufp, size_t *sizep);

这段代码有问题吗,还是我需要看一下我的编译器?我想以正确的方式摆脱这个警告。


更新:

使用 gcc 4.3.2、glibc 2.9


更新 2:

尝试了以下方法:

powerpc-860-linux-gnu-gcc -std=c99 -Wall -D_XOPEN_SOURCE=700 -c source.c

结果:

source.c: In function 'main':
source.c:12: warning: implicit declaration of function 'open_memstream'
source.c:12: warning: assignment makes pointer from integer without a cast

根据this,似乎_XOPEN_SOURCE=700 可用从glibc 2.10开始。

由于我使用的是 glibc 2.9,我还有哪些其他选择(除了升级 glibc)?


更新 3:

添加以下内容消除了警告:

extern FILE *open_memstream(char **bufp, size_t *sizep);

这个解决方案有什么问题吗?


更新 4:

这代替了外部:

powerpc-860-linux-gnu-gcc -std=c99 -Wall -D_GNU_SOURCE -c ops_cmds.c

所以根据manpage,如果glibc pre-2.10(在我的情况下)需要使用_GNU_SOURCE,如果2.10+需要使用_XOPEN_SOURCE=700

【问题讨论】:

    标签: c linux embedded


    【解决方案1】:

    定义:

    #define _POSIX_C_SOURCE 200809L
    

    #define _XOPEN_SOURCE 700
    

    在您的源代码中包含stdio.h 之前。或者使用gcc,您可以使用-D 选项定义宏值并将其传递给源文件:

    gcc -std=c99 -Wall -D_XOPEN_SOURCE=700 -c source.c 
    

    open_memstream 是一个 POSIX 函数,如果没有这个定义,它的声明在你的程序中是不可见的。

    【讨论】:

    • +1,但我会考虑在编译期间使用-D_XOPEN_SOURCE=700,因为在某些文件中很容易忘记定义,或者忘记保留它first。也许你可以在这里添加一些关于最佳实践的内容。
    • @AntonKovalenko 好的,我添加了对-D 标志的提及。
    • +1,不知道这个,谢谢。尝试了您的示例但仍然有问题,我认为这是因为我有一个较旧的 glibc。查看更新的问题。
    • @mikhail open_memstream 的联机帮助页说您必须定义 _GNU_SOURCE 以使该函数在 glibc 2.10 之前的 glibc 版本中可用。您也可以考虑使用 -std=gnu99。
    • @nos 完美!我现在在联机帮助页上看到了这一点,并且有效。所以 _GNU_SOURCE 如果 glibc pre-2.10 和 _XOPEN_SOURCE=700 如果 2.10+。
    【解决方案2】:

    编译器抱怨的是open_memstream返回值,而不是你传入的参数。

    您的open_memstream 未声明,即编译器看不到原型。所以编译器(显然是 C99 之前的版本)假定它返回一个 int。您将 int 强制转换为 stream 指针,这会触发有关“使指针形成整数”的警告。

    确保在尝试使用 open_memstream 之前已声明它。原型应该位于stdio.h,但它仅在 POSIX.1-2008 中可用。您必须明确启用它(请参阅其他答案)。

    【讨论】:

    • 编译器可以是c99编译器。 gcc-std=c99 不会定义 POSIX 宏。
    • @ouah:C99 编译器没有“隐式 int”规则,这意味着不允许 C99 编译器假定未声明的函数返回 int。 OP 看到的诊断消息在 C99 的上下文中将具有误导性且毫无意义。这就是为什么我猜测他的编译器是 C99 之前的。
    • c99 需要对隐式声明进行诊断。 gcc -std=c99 没有 -Werror 选项会发出诊断,但不会导致翻译失败。
    • +1,谢谢,添加 -Wall 表明情况就是这样,问题已更新。仍然不确定如何解决。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 2010-11-19
    相关资源
    最近更新 更多