C, C++, грабли
Jul. 11th, 2019 07:28 pmНаступил на грабли. gcc и g++ дают разный размер довольно развесистой структуры, используемой в сишной и плюсовой библиотеках.
Можно ли малой кровью их привести к единому знаменателю? С-шная библиотека не наша, плюсовая наша.
Вроде бы везде стоят флаги
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
Опцию -fpack-struct пробовал, не преуспел.
Update: разные опции сборки базовой и производной библиотек.
Можно ли малой кровью их привести к единому знаменателю? С-шная библиотека не наша, плюсовая наша.
Вроде бы везде стоят флаги
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
Опцию -fpack-struct пробовал, не преуспел.
Update: разные опции сборки базовой и производной библиотек.
no subject
Date: 2019-07-11 04:47 pm (UTC)Впрочем я бы сначала попробовал вывести куда-нибудь в отладочный вывод offsetof всех полей и посмотреть где именно начинается расхождение.
no subject
Date: 2019-07-11 05:13 pm (UTC)То есть даже если сейчас найти ключ, с которым заработает, то не факт что не сломается в следующей версии или на другом процессоре.
no subject
Date: 2019-07-11 05:33 pm (UTC)no subject
Date: 2019-07-11 05:42 pm (UTC)То есть скорее всего я плюсовую библиотеку сконвертирую в C-шную, и надеюсь, что этого мне хватит.
no subject
Date: 2019-07-11 06:00 pm (UTC)Кажется, такая порнография еще не запрещена и результат нужный выдаст...
no subject
Date: 2019-07-11 06:14 pm (UTC)no subject
Date: 2019-07-11 07:02 pm (UTC)char pseudostruct[16]; /* int, char[4], double */ int get_a(char* p){ return *((int*)p); } void set_a(char* p, int v){ *((int*)p) = v; } char* get_b(char* p){ return p + 4; } void set_b(char* p, char* v){ strncpy(p, v, 4); } double get_c(char* p){ return *((double*)(p + 8)); } void set_c(char* p, double v){ *((double*)(p + 8)) = v; }Обвешать inline по вкусу. Но это уже подозрительно напоминает попытку ASM-вставки без ASM-вставки и той самой ручной оптимизации, которая очень эффективно замедляет код.
no subject
Date: 2019-07-11 07:08 pm (UTC)no subject
Date: 2019-07-11 08:07 pm (UTC)no subject
Date: 2019-07-11 08:59 pm (UTC)no subject
Date: 2019-07-11 09:34 pm (UTC)Если нет, то я бы всё-таки вначале понял, где именно возникает расхождение - тупо получил от C-библиотеки структуру с известными полями и посмотрел в памяти. Потому что понятно что стандарт двоичной совместимости не гарантирует, но практически расхождение странное, я бы сомневался в точности диагноза. Опять же, если понять какой тип вызывает проблемы, может получиться обойтись малой кровью.
no subject
Date: 2019-07-11 09:49 pm (UTC)no subject
Date: 2019-07-12 04:57 am (UTC)Более того, вообще-то и разные компиляторы на одной архитектуре - тоже.
Потому что в системных ABI разных операционных систем ДО ХРЕНА структур, передаваемых как параметры и как-то это работает.
no subject
Date: 2019-07-12 05:01 am (UTC)no subject
Date: 2019-07-12 05:17 am (UTC)Кстати, интересно, в Герцогстве Горностайском (в смысле Ubuntu eoan ermine) уже 9 или еще не втащили. Ну в понедельник на работу выйду, посмотрю.
no subject
Date: 2019-07-12 06:37 am (UTC)no subject
Date: 2019-07-12 06:50 am (UTC)6-й Редхат и 11 SLES пока вполне актуальны. Кстати, не дождался понедельника и скачал
http://archive.ubuntu.com/ubuntu/dists/eoan/binary-amd64/Packages.gz.
Там уже 9.1.
no subject
Date: 2019-07-12 06:51 am (UTC)Мой научник 20 лет назад поминал идею о том, что иногда стоит сделать конский malloc(), а дальше внутри него раскладывать то, что тебе нужно, по сути, реализуя свой маленький менеджер памяти. Это вот ровно то же самое; подозреваю, это до сих пор верно в ситуациях, когда у тебя 64К памяти, и ты реально лучше любого компилятора знаешь, что где как должно лежать.
no subject
Date: 2019-07-12 11:27 am (UTC)Возможно, в более новой версии это уже починено, но пока у меня нет достаточно не-знаю-чего для вычленения криптокомовских патчей и переноса их на новую версию.
no subject
Date: 2019-07-12 11:29 am (UTC)no subject
Date: 2019-07-12 02:56 pm (UTC)no subject
Date: 2019-07-12 03:50 pm (UTC)В Си++ у стрктуры-класса будет дефолтные конструктор и деструктор, создавать их надо через new (или на стеке). В Си у структуры нет никаких деструкторов, создавать их надо через malloc.
no subject
Date: 2019-07-12 07:08 pm (UTC)no subject
Date: 2019-07-15 08:03 am (UTC)Это часть стандарта?
no subject
Date: 2019-07-15 12:31 pm (UTC)Что значит «в связке с Си»? Стандарты C и C++ не специфицируют точное представление типов, оставляя это на откуп реализации. Реализации же в большинстве своём делают в соответствии с ABI платформы. Раскладывать плюсовую структуру совместимо с аналогичной сишной — в большинстве случаев достаточно экономично по памяти и быстродействию и выгодно для interoperability.
Плюсовые структуры, удовлетворяющие требованиям на plain old data (C++11 [class]#6–10), будучи побайтово скопированы в байтовый буфер, а затем обратно в память, занятую экземпляром той же самой структуры — остаются валидными объектами, почленно равными исходным (C++11 [basic.types]#2). Указатель на POD-структуру численно равен указателю на её первое поле (C++11 [class.mem]#17–20). Да, здесь нет явного разрешения копировать полученный извне байтовый массив в underlying bytes структуры и рассчитывать на правильную интерпретацию; это, на самом деле, к ABI.