Как интерпретировать структуру без определения? - PullRequest
5 голосов
/ 26 декабря 2011

Сегодня я начал работать с открытым исходным кодом FUSE, там я нашел несколько строк вроде этого:

struct fuse_session;
struct fuse_chan;

Я не знаю, как это интерпретировать, насколько я знал, что 'struct'затем имя структуры и затем имя переменной.Если, как в данном случае, существует только одна именованная сущность, за которой следует struct, то этот сеанс плавкого предохранителя является структурной переменной или самим структурным именем. Это может быть действительно простой вещью, но я нигде не могу ее найти.

Ответы [ 5 ]

10 голосов
/ 26 декабря 2011

Это обычно используется для одного из следующих действий:

  1. Вы хотите, чтобы пользователь какого-либо модуля знал, что эта структура существует, но не хочет показывать ее содержимое,Например:

    в api.h:

    struct bar;
    
    void GetStruct(struct bar *);
    void SetActive(struct bar *, char);
    

    во внутреннем файле:

    struct bar {
        char is_active;
    };
    
    void GetStruct(struct bar * st) {
        st = malloc(sizeof(struct bar));
    }
    
    void SetActive(struct bar * st, char active) {
        if (st != NULL)
            st->is_active = active;
    }
    

    Таким образом вы инкапсулируете реализацию и можете изменить структуру позже, еслинеобходимо без какого-либо влияния на используемый модуль.

  2. Вы хотите использовать структуру (указатель) перед ее объявлением.Например:

    struct bar;
    typedef int (*FooFuncType)(struct bar *);
    struct bar {
        FooFuncType a_func;        
    };
    

Одно важное замечание:

Если у вас есть только объявление структуры, как в вашем вопросе, вы не можете ссылаться на структуру напрямую илиВы можете использовать оператор sizeof, только объявить указатель на структуру.

2 голосов
/ 26 декабря 2011

Вы должны получить введение в forward declaration в C. Пожалуйста, попробуйте эту ссылку.

2 голосов
/ 26 декабря 2011

Это неполные или непрозрачные типы, и они полезны, когда интерфейс библиотеки работает только с указателями на эти типы.Вам не нужно заполнять все детали того, что находится в структурах, поэтому никакой код вне библиотеки никогда не сможет получить доступ к данным в структуре (законно).Код внутри библиотеки имеет закрытый заголовок, который предоставляет подробные сведения о том, что находится в структурах, поэтому библиотека действительно может работать с содержимым, но эта деталь скрыта от потребителей библиотеки.

Incompleteтипы обеспечивают намного лучшую безопасность типов, чем другая альтернатива, которая иногда используется, а именно пустые указатели.Слишком легко запутаться, когда есть несколько различных типов, представленных как 'void *'.С неполными типами вы можете правильно различать разные типы, но все же не раскрывать детали того, как они реализованы.

0 голосов
/ 26 декабря 2011

Forward Declaration это помогает компилятору разрешать структурные ссылки из разных частей программы.

0 голосов
/ 26 декабря 2011

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

...