С++ зарезервированный символ как имя переменной C

Я использую внешнюю библиотеку C внутри проекта С++.

Заголовок содержит структуру с переменной с именем class:

#ifdef __cplusplus
extern "C" {
#endif

struct something_t {
    ...
    sometype class;
};


#ifdef __cplusplus
}
#endif

g++ не нравится это и жалуется на "ошибка: ожидаемый идентификатор до"; лексема".

Какие у меня есть варианты?

  • Я мог бы переименовать class, но это громоздко и разрывает совместимость с восходящим потоком.
  • Я мог бы попросить восходящий проект переименовать переменную, но это может быть сложно.
  • Я мог бы переопределить class в заголовке с помощью препроцессора: #define class class_ Есть ли какие-либо побочные эффекты?
  • Любые другие предложения?

Какой лучший способ справиться с этой ситуацией?

Результат: Основываясь на преобладающем предпочтении опции 2, я, наконец, решил инициировать переименование в восходящей библиотеке.

Ответы

Ответ 1

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

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

В С++ вы можете использовать очищенный C-API.


Здесь небольшой эскиз:

ThirdParty.h (содержит код для компиляции с С++)

#ifdef __cplusplus
extern "C" {
#endif

struct something_t {
    ...
    sometype class;
};

struct something_t* CreateSomething(); // Does memory allocation and initialization
void DoSomething(struct something_t* something);

#ifdef __cplusplus
}
#endif

MyApiWrapper.h

#ifdef __cplusplus
extern "C" {
#endif

typedef void* psomething_t;

struct psomething_t MyCreateSomething(); // Does memory allocation and initialization
void MyDoSomething(psomething_t something);

#ifdef __cplusplus
}
#endif

MyApiWrapper.c

#include "ThirdParty.h"

struct psomething_t MyCreateSomething() {
     psomething_t psomething = (psomething_t)CreateSomething();
     return psomething;
}

void MyDoSomething(psomething_t something) {
    DoSomething((struct something_t*)psomething);
}

Относительно ваших рассмотренных решений

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

Вы должны сообщить об ошибке, чтобы сообщить им об этом. Если это проект git -hub, подготовьте запрос на pull.

В любом случае будьте готовы к тому, что они могут не реагировать своевременно, и вы всегда должны иметь вышеупомянутый "план B". Он будет работать независимо...

  1. Я могу переопределить класс в заголовке с помощью препроцессора: #define class class_ Есть ли какие-либо побочные эффекты?

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