Можно скомпилировать любой файл .c изолированно (то есть без основного?) - PullRequest
5 голосов
/ 17 ноября 2010

В настоящее время у меня есть «подобный библиотеке» файл .c (который будет показан ниже).У меня есть 2 вопроса об этом:

  1. Если я хочу посмотреть, хорошо ли он компилируется для себя, как я могу это сделать?Если я попытаюсь сделать это gcc, он всегда выдаст ошибку «no main», что имеет смысл, но поднимает проблему определения, хорошо ли скомпилируется данный файл .c или нет в «изоляции».Могу ли я с уверенностью заключить, что если единственная ошибка, с которой столкнулся компилятор, это «нет основной», мой файл в порядке?Примером того, где компиляция .c файлов в отдельности могла бы быть полезной, было бы определить, какие из них являются избыточными, здесь.

  2. Есть ли в простом файле, подобном этому, точка для определениязаголовок с его объявлениями метода / структуры, а затем такой крошечный файл .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);
    
    
    <pre><code>free(semaforo);
    
    } #endif

Спасибо

Ответы [ 3 ]

10 голосов
/ 17 ноября 2010

Чтобы скомпилировать его без компоновки (не требует главной точки входа):

cc -c file.c -o file.o

Даже для небольшого файла, который определяет подпрограммы, которые будут вызываться из других исходных файлов, вы все равно хотите файл заголовка,Заголовочный файл - это то, как компилятор знает интерфейс с подпрограммами, прежде чем компоновщик свяжет их все вместе.Если у вас нет объявлений для функций, которые являются внешними, то компилятор должен сделать предположения (обычно неправильные) о типах данных параметров.Вы можете объявить функции в каждом исходном файле, в котором они используются, но суть заголовочных файлов такова, что вы просто делаете это один раз в заголовочном файле.

3 голосов
/ 17 ноября 2010

Опция -c для gcc - это то, что вам не хватает, которая компилирует один файл .c в файл .o.

Ответ на ваш второй вопрос «уверен». Это хорошая привычка - не вводить externs во все файлы .c, которые хотят использовать какую-либо общую функцию или другую. Каждый маленький .h помогает.

2 голосов
/ 17 ноября 2010

Что касается второго вопроса, я хотел бы знать, почему!

Чтобы ответить на пункт 2, хранение объявлений в заголовочном файле помогает избежать ситуаций, подобных следующей.

Вы решаете, что вам нужно отслеживать своих цыплят в file.c:

int number_of_chickens;

В file2.c вы решаете, что было бы хорошей идеей представить числокуры как двойные вместо целых, но вы забыли обновить 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 как имя, ссылающееся на 4-битное целое в file.c и 8-битное двойное в file2.c.

Если вы вызовете функцию count_chickens, она вернет мусор (старшие 32 бита двойного будут заполнены содержимым int number_of_chickens, младшие 32 бита будут неопределенными - что будет послеnumber_of_chickens в памяти).

Еще хуже, когда вы вызываете add_to_chickens(1) в file2.c, вы записываете 8 байтов в 4-байтовое хранилище, что, безусловно, вызывает хаос, но не обязательно вызывает ошибку времени выполнения (по крайней мере, не сразу).

Если вы храните внешнюю декларацию в общем заголовочном файле, вы сразу получаете ошибку времени компиляции.Если вы этого не сделаете, вы получите необъяснимую нестабильность через 3 месяца после отправки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...