从函数中分配void指针可在一个源文件中工作,但不能在两个源文件中工作

时间:2014-05-11 04:37:19

标签: c pointers gcc casting

所以我正在使用this chapter of a sweet modern OpenGL tutorial,并且在部分代码中,我将void指针变量分配给第二个文件中void *函数的返回值。我从gcc:initialization makes pointer from integer without a cast收到此错误。作为测试,我尝试合并这两个文件并再次编译。这次,函数与调用它的文件在同一个文件中,我没有错误。

我能用三个最小的文件重现这个:

file1.c中

void main() {
    void *newval = foo();
}

file2.c中

#include <stdlib.h>

void *foo() {
    void *val;
    val = malloc(10);
    return val;
}

file3.c中

#include <stdlib.h>

void *foo() {
    void *val;
    val = malloc(10);
    return val;
}

void main() {
    void *newval = foo();
}

file3.c只是前两个组合。我的问题是为什么当我编译一种方式时我得到一个错误,另一种方式我没有得到:

  

$ gcc file1.c file2.c
file1.c:在函数'main'中:file1.c:2:17:   警告:初始化使得指针来自整数而没有强制转换   [默认启用]
$ gcc file3.c
$

我认为file1.c + file2.c combo与file3.c完全相同。我错过了什么?

2 个答案:

答案 0 :(得分:2)

您需要声明foo()函数,以便编译器在编译file1.c时知道它是什么。

创建file2.h并添加

void *foo();

将其包含在file.c中

#include "file2.h"

如果没有声明,编译器会将所有未知函数假定为返回int,但是当您的函数返回void *并且您将其分配给void *时,它会尝试分配int } void *因此你得到了警告。

答案 1 :(得分:2)

file1.c中,似乎缺少void *foo()的声明。 您可以包含包含此声明的标题文件,也可以在void *foo()之上添加第file1.c行。

当编译器在主文件中找到符号foo后跟(,并且没有声明时,它假定foo接受任意数量的参数并返回一个int。因此,您会看到int正在转换为指针的警告。

但是在文件file3.c中,符号foo是已知的,因为它是第一次使用之前定义的函数,因此编译器知道foo返回一个指针,因此没有警告。