我有以下两个.c
文件
main.c中
#include <stdio.h>
int print();
int show(int);
int main()
{
int i = 0;
float x = 1.0;
int y = *((int*)(&x));
print();
i = show(5);
printf("%d", i);
printf("\n%d", y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
foo.c的
#include <stdio.h>
void print()
{
printf("Hello World !!\n");
}
float show()
{
return 1;
}
Run Code Online (Sandbox Code Playgroud)
这是我的 makefile
CC = gcc
CFLAGS = -I. -Wall -pedantic -Wconversion
.PHONY: clean
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
main: main.o foo.o
$(CC) -o main main.o foo.o $(CFLAGS)
clean:
rm -rf *.o
rm -rf main
Run Code Online (Sandbox Code Playgroud)
这是输出
你好,世界 !!
1065353216
1065353216
如果我构建上述内容,绝对没有错误.看来,链接gcc
并不关心这两个函数有不同的返回类型和不同的参数列表.
第二点是在函数中show
而不是从float
to 进行隐式转换int
,比特模式被复制,我已经使用第二次printf
调用验证了.
为什么上面发生了什么?我知道这不会g++
因名称损坏而发生,但这不是一个严重的问题吗?
诀窍是在头文件 ( foo.h
) 中声明您的函数,然后将该头文件包含在源文件 ( foo.c
) 中。main.c
还要在调用 foo.h 中声明的函数的 任何源文件(例如 )中包含头文件。
包含foo.h
infoo.c
允许编译器验证函数声明是否与函数定义匹配。包括foo.h
让main.c
编译器验证 main.c 是否正确使用函数,并且还允许编译器进行任何必要的类型转换。
正如您发现的那样,通过错误地声明 main.c 中的函数来欺骗编译器,这对您没有好处。
foo.h
void print( void );
float show( void );
Run Code Online (Sandbox Code Playgroud)
主程序
#include <stdio.h>
#include "foo.h"
int main()
{
int i = 0;
print();
i = show();
printf("%d\n", i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
foo.c
#include <stdio.h>
#include "foo.h"
void print( void )
{
printf("Hello World !!\n");
}
float show( void )
{
return 2;
}
Run Code Online (Sandbox Code Playgroud)