我目前有一个“类似库”的.c文件(将在下面显示)。我有两个问题:
如果我想看看它是否能很好地编译,我该怎么办呢?如果我尝试gcc它,它将始终给出一个“无主”错误,这是有道理的,但提出了一个问题,即知道给定的.c文件是否能在“隔离”中编译好。我可以安全地得出结论,如果编译器引发的唯一错误是“无主”,我的文件没问题吗?在这里单独编译.c文件可能很好的一个例子就是确定哪些包含过多,在这里。
这样的简单文件中是否有一个点用它的方法/结构声明定义一个标题,然后有一个带有代码实现的微小的.c文件?
#ifndef SEMAFOROS
#define SEMAFOROS
#include <signal.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
typedef struct {
sem_t* id;
char* nome;
} Semaforo;
inline void lock(Semaforo* semaforo) {
sem_wait(semaforo->id);
}
inline void unlock(Semaforo* semaforo) {
sem_post(semaforo->id);
}
Semaforo* criarSemaforo(char* nome) {
Semaforo* semaforo = (Semaforo*)malloc(sizeof(Semaforo));
semaforo->id = sem_open(nome, O_CREAT, 0xFFFFFFF, 1);
semaforo->nome = nome;
}
void destruirSemaforo(Semaforo* semaforo) {
sem_close(semaforo->id);
sem_unlink(semaforo->nome);
free(semaforo);
}
#endif
由于
答案 0 :(得分:10)
要编译它而不进行链接(不需要主入口点):
cc -c file.c -o file.o
即使对于定义将从其他源文件调用的例程的小文件,您仍然需要头文件。头文件是编译器在链接器将它们连接在一起之前知道例程的接口的方式。如果您没有外部函数的声明,则编译器必须对参数的数据类型进行假设(通常是错误的)。您可以在每个使用它们的源文件中声明函数,但是头文件的位置是这样的,您只需在头文件中执行一次。
答案 1 :(得分:3)
gcc的-c
选项似乎是您所缺少的,它将一个.c文件编译为.o文件。
你的第二个问题的答案是'确定'。这是一个很好的习惯,不要在所有想要使用某个共享功能的.c文件中输入externs。每一点.h都有帮助。
答案 2 :(得分:2)
对于第二个问题,我想知道原因!
要回答第2点,在头文件中保留声明可以帮助您避免以下情况。
您决定需要在file.c
中跟踪您的鸡:
int number_of_chickens;
在file2.c
中,您决定将鸡的数量表示为double而不是int,这是一个好主意,但您忘记更新file.c
:
extern double number_of_chickens;
double count_chickens() {
return number_of_chickens;
}
void add_to_chickens(double how_many) {
number_of_chickens += how_many;
}
这将编译得很好。链接器会将number_of_chickens
视为引用file.c
中4位int的名称,并将file2.c
中的8位加倍。
如果你调用count_chickens
函数,它将返回垃圾(double的高32位将用int number_of_chickens
的内容填充,低32位将是未定义的 - 无论来什么在记忆中number_of_chickens
后。
更糟糕的是,当你在add_to_chickens(1)
中调用file2.c
时,你会将8个字节写入4字节的存储位置,肯定会造成严重破坏,但不一定会导致运行时错误(至少,不对远)。
如果将外部声明保存在公共头文件中,则会立即收到编译时错误。如果不这样做,则在发货3个月后会出现无法解释的不稳定因素。