Как включить заголовочный файл c в другой заголовок? - PullRequest
1 голос
/ 25 марта 2019

Я пишу программу на языке c, используя библиотеку curses, и хочу создать некоторые структуры, отражающие пользовательский интерфейс моего приложения.

Вот мой app.c файл

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

int main() {
    struct screen scr = {
        .win1 = {
            .title = "win1"
        },
        .win2 = {
            .title = "win2"
        }
    };
}

вот screen.h

#ifndef SCREEN_H
#define SCREEN_H

#include "window.h"

struct screen {
    struct window win1;
    struct window win2;

    struct window *focused;
};

#endif

а вот window.h

#ifndef WINDOW_H
#define WINDOW_H

#include "screen.h"

struct window {
    char *title;
    void (*handle_key_event)(struct screen*);
};

#endif

Мой метод дескриптора структуры окна должен получить ссылку на экран, чтобы иметь возможность изменять сфокусированное окно в некоторых конкретных случаях. Но когда я компилирую это, я получаю предупреждение

window.h:8:34: warning: its scope is only this definition or declaration, which is probably not what you want

потому что он не видит экранное объявление. Как это исправить?

Ответы [ 2 ]

4 голосов
/ 25 марта 2019

Предупреждение, когда первая ссылка на структуру находится внутри чего-то другого.

Поставьте struct screen; выше объявления struct window.

Круговые зависимости заголовочных файлов - плохая идея. Рассмотрим рефакторинг. Вам не нужно определение структуры для объявления указателей на нее. Предварительной декларации будет достаточно.

2 голосов
/ 25 марта 2019

Речь идет о фундаментальном дизайне, больше ничего.Иметь два заголовочных файла, которые взаимно включают друг друга, просто не имеет никакого смысла, не делайте этого.#include следует рассматривать как одностороннюю зависимость.При разработке программы более сложные объекты зависят от менее сложных объектов и состоят из них.

Например, экран содержит окно, поэтому оно должно быть тем, которое выполняет #include "window.h".Хотя окно ничего не знает об экранах, оно должно заниматься только отображением окна.Перекрестная связь между двумя модулями может потребоваться в третьем модуле.

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