Несовместимость компиляции C vs C++ - не называет тип



Я пытаюсь использовать библиотеку поставщика в сочетании с моим приложением C++. Библиотека в основном основана на C, что обычно не является проблемой с extern "C" вариант, но я столкнулся с проблемой, которую компилятор C++ не принимает.



я упростил свой код в следующие файлы примеров. заголовок.h представляет заголовок из библиотеки Supper, main.c / cpp - это мои собственные файлы. Мое реальное приложение-это приложение на C++, поэтому я хочу, чтобы оно работало с main.СРР.



заголовок.ч (обратите внимание на строку u64 u64;):



#ifndef HEADER_H
#define HEADER_H

#include <stdint.h>

typedef uint64_t u64;

union teststruct {
u64 u64;
struct {
u64 x:32;
u64 y:32;
} s;
};

#endif


главная.c:



#include <stdio.h>
#include "header.h"

int main() {
union teststruct a;
a.u64=5;
printf("%xn", a.u64);

return 0;
}


главная.СРР (аналогично главной.c но с дополнительным extern "C" заявления):



#include <stdio.h>

extern "C" {
#include "header.h"
}

int main() {
union teststruct a;
a.u64=5;
printf("%xn", a.u64);

return 0;
}


компиляция main.c помощью строки



gcc -o test main.c


компилируется без проблем. Однако компиляция версии C++ с помощью компилятора g++ с командой



g++ -o test main.cpp


выдает следующие ошибки компилятора:



In file included from main.cpp:12:0:
header.h:11:9: error: ‘u64’ does not name a type
u64 x:32;
^
header.h:12:9: error: ‘u64’ does not name a type
u64 y:32;
^


проблема в том, что поставщик используется одно и то же имя (u64) как для типа, так и для имени переменной, что кажется плохой идеей, но gcc, по-видимому, принимает его. Я не хочу менять библиотеку (т. е. заголовок.з) так как он очень большой,это происходит много в коде, и я иногда получаю обновления для него. Есть ли способ заставить g++ принять эту комбинацию или способ изменить main.cpp, чтобы сделать его компилировать без изменение заголовка.ч?

706   3  

3 ответов:

teststruct определяет область в C++. Вы можете сформировать квалифицированный идентификатор teststruct::u64. Таким образом, правила языка для поиска имен учитывают это, позволяя членам классов и союзов скрывать идентификаторы во внешней области. Один раз u64 u64; вводится, безусловного u64 не может ссылаться на глобальный ::u64, только член. И член не является типом.

В C union teststruct не определяет объем. Поле может использоваться только в доступе к члену, поэтому никогда не может возникнуть конфликт. По существу поле не должно скрывать идентификатор типа области действия файла.

насколько я могу судить, вы ничего не можете сделать, чтобы легко обойти это. Эта библиотека (которая является совершенно допустимой библиотекой C), не является допустимой библиотекой C++. Не отличается от того, если бы он использовал new или try в качестве имен переменных. Его нужно адаптировать.

кажется, что у вас есть файл заголовка, который является незаконным в C++, поэтому вы не можете #include Это в коде, скомпилированном как C++. Если вы не можете изменить файл заголовка библиотеки (например, пожаловавшись поставщику библиотеки), то самый простой вариант-написать тонкую c++-совместимую оболочку вокруг библиотеки:

чтобы изолировать код C++ от заголовка C, создайте Wrapper.h и Wrapper.c, где .h действительно для включения в C++, делает не включить header.h, и предоставляет все типы и функции, необходимые для взаимодействия с библиотекой. Затем, в .c вы можете #include "header.h" и реализовать все звонки (и все, что вам нужно сделать, чтобы безопасно конвертировать между типами). Это, очевидно, должно быть скомпилировано как C, а не C++.

если ваша упомянутая несовместимость между C и C++ является единственной, вы должны иметь возможность конвертировать header.h чтобы c++ совместимый файл заголовка программно, назовите его что-то вроде header.hpp. И тогда вы можете конвертировать новые версии таким же образом.

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

header.h:11:9: error: ‘u64’ does not name a type
  1. открыть header.h;
  2. искать позицию 11:9;
  3. вставить :: там;
  4. повторите для всех does not name a type ошибка.

обработка строк и готово.

PS: конвертеры C в C++ тоже могут это сделать.

Comments

    Ничего не найдено.