Заголовок C и C ++: определение глобальной структуры внутри другой структуры - PullRequest
4 голосов
/ 27 марта 2019

У меня есть некоторый код C, который имеет некоторые структуры, которые выглядят следующим образом:

typedef struct my_library_a_t my_library_a_t;
typedef struct my_library_b_t my_library_b_t;
typedef struct my_library_c_t my_library_c_t;

struct my_library_a_t {
    struct my_library_b_t {
        int data;
        struct my_library_c_t {
            int data;
        } c;
    } b;
    int data;
};

Это не работает в C ++, потому что в C struct my_library_b_t определяет глобальный struct my_library_b_t, тогда как в C ++он определяет ::my_library_a_t::my_library_b_t.

Как я могу получить определение внутренней структуры для определения глобальной структуры в C ++?Или даже просто не нужно менять слишком много кода, чтобы он работал (я не против иметь блок #ifdef __cplusplus, но я не хочу выделять структуры, потому что причина, по которой они вложены в первую очередь, заключается в том, чтоони используются только один раз каждый, и действительно трудно читать, когда определения внутреннего класса находятся выше определений внешнего класса)

Я попытался struct ::my_library_b_t в определении, но это не работает.

Для контекста я разбираю строку с определением, которое будет выглядеть следующим образом:

a     = b "," data
b     = data "," c
c     = data
data  = %x31-39 *DIGIT  ; 1-9 followed by *(0-9)
      / "0"

А промежуточные части имеют значение, поэтому полезно иметь возможность иметь функции, которые принимаютmy_library_b_t* или my_library_c_t*.

Я бы предпочел иметь решение, которое выглядит следующим образом:

#ifdef __cplusplus
#define GLOBAL_STRUCT(name) ???  (I tried `:: name`)
extern "C" {
#else
#define GLOBAL_STRUCT(name) name
#endif

struct my_library_a_t {
    struct GLOBAL_STRUCT(my_library_b_t) {
// ...

1 Ответ

1 голос
/ 28 марта 2019

Я рекомендую это

struct my_library_a_t {
    struct my_library_b_t {
        int data;
        struct my_library_c_t {
            int data;
        } c;
    } b;
    int data;
};
#ifdef __cplusplus
    typedef struct my_library_a_t::my_library_b_t my_library_b_t;
    typedef struct my_library_b_t::my_library_c_t my_library_c_t;
#else
    typedef struct my_library_a_t my_library_a_t;
    typedef struct my_library_b_t my_library_b_t;
    typedef struct my_library_c_t my_library_c_t;
#endif

Обратите внимание, что после псевдонима my_library_b_t вам не нужно использовать my_library_a_t :: my_library_b_t :: my_library_c_t

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