LINUX.ORG.RU

Написание кода на C, совместимом с C++

 , ,


1

3

Есть какой-нибудь гайд по написанию кода на C таким образом, чтобы он компилировался и корректно работал будучи скомпилированным и плюсовым и С компилятором? В чем там основные несовместимости? Например если надо написать некий код, который надо будет запихивать в устройство, под которое есть только C компилятор, но при этом чтобы было возможным переиспользовать этот код в плюсах, дополнив его плюсовой фигней. На какую версию стандарта C лучше ориентироваться и какие фичи из C отсутствуют в C++?

★★★★★
Ответ на: комментарий от tailgunner

Да, драфт я нашел какой-то http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

Только там непонятно, с какой конкретно версией стандарта C идет сравнение совместимости

This subclause lists the differences between C++ and ISO C, by the chapters of this document

Например в новых стандартах C есть массивы, размер которых можно задать через переменную, при этом программа выделит нужное место на стеке. В плюсах этого нет

int char[a];
Беглый просмотр Annex C1 из драфта не выявил указания, что такая фича в плюсах отсутствует

SZT ★★★★★
() автор топика
Ответ на: комментарий от SZT

Суть в том, что стандарты 2011 и 2014 ссылаются на С99. С++11 вышел раньше С11, а С++14 - мелкий релиз, куда такого не совали.

Pavval ★★★★★
()

чтобы было возможным переиспользовать этот код в плюсах, дополнив его плюсовой фигней

в чем проблема добавить в заголовки extern «C» и использовать код как сишный?

annulen ★★★★★
()
Ответ на: комментарий от annulen

В том что например for (int i=0; i <0; i++) не осилит C компиллер, он скажет объявите i отдельно. И таких ньюансов полно.

anonymous
()
Ответ на: комментарий от annulen

И в соответствии с какой версией стандарта С это будет компилироваться? К тому же прочитай ОП-пост. Там написано

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

Дополнить плюсовой фигней код, заключенный в extern C уже не выйдет

SZT ★★★★★
() автор топика
Ответ на: комментарий от anonymous

В том что например for (int i=0; i <0; i++) не осилит C компиллер, он скажет объявите i отдельно. И таких ньюансов полно.

-std=gnu99 точно решает эту проблему для си.

А вообще в крайнем случае ifdef-ами разделаться.

Krieger_Od ★★
()
Ответ на: комментарий от SZT

Дополнить плюсовой фигней код, заключенный в extern C уже не выйдет

Дык не надо смешивать сишный код с плюсовой фигней, ее можно сверху обернуть

annulen ★★★★★
()
Ответ на: комментарий от SZT

Массивы переменной длины(variable-length arrays) были введены еще в C99

Интересно, смахивает на упущение стандарта. Кстати в С11 они есть только если _ _STDC_NO_VLA_ _ не определен, хотя в С99 были безусловно.

Pavval ★★★★★
()
Ответ на: комментарий от anonymous

В том что например for (int i=0; i <0; i++) не осилит C компиллер

Это давно уже в c99

mashina ★★★★★
()
Ответ на: комментарий от SZT

Беглый просмотр Annex C1 из драфта не выявил указания, что такая фича в плюсах отсутствует

Ну так она там как раз присутствует.

anonymous
()
Ответ на: комментарий от anonymous

Откуда? Компилируй с опцией -pedantic

warning: variable length arrays are a C99 feature [-Wvla-extension]

SZT ★★★★★
() автор топика

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

Iron_Bug ★★★★★
()
Ответ на: комментарий от Pavval

смахивает на упущение стандарта

Насколько мне известно, VLA не были добавлены в C++ умышленно. И правильно, нечего всякий бред тянуть, начиная с C99 разработка языка явно пошла под какими-то суровыми веществами.

Gvidon ★★★★
()
Ответ на: комментарий от SZT

С++. extern «C» просто отключает декорацию имён, он не имеет никакого отношения к тому, что за этими именами скрывается.

Gvidon ★★★★
()
Ответ на: комментарий от anonymous

В том что например for (int i=0; i <0; i++) не осилит C компиллер

... не осилит, если не умеет в C99.

KennyMinigun ★★★★★
()
Ответ на: комментарий от Gvidon

А какие есть альтернативы этому VLA? Как выделить на стеке неизвестно какое количество байт одним куском? alloca() например вообще никак не стандартизирован, и поведение у него будет отличатся. Память, выделенная через alloca() будет возвращена в стек только после завершения функции, где эту alloca() вызвали, а с VLA освобождение памяти должно произойти когда закончится область видимости соответствующего VLA

SZT ★★★★★
() автор топика
Ответ на: комментарий от Gvidon

Насколько мне известно, VLA не были добавлены в C++ умышленно. И правильно, нечего всякий бред тянуть, начиная с C99 разработка языка явно пошла под какими-то суровыми веществами.

Причем тут VLA? Я говорю про упущение описания разницы в Annex C1.

Pavval ★★★★★
()
Ответ на: комментарий от SZT

Как выделить на стеке неизвестно какое количество байт одним куском?

Никак, да и нефиг. Реализация VLA возможна не для всех платформ, потому и нефиг ее в язык пихать. А проблем у VLA хватает - типа stack overflow без возможности обработки (сходу имеешь способ DOS атак).

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Реализация VLA возможна не для всех платформ

А для каких платформ она невозможна? Не вижу никаких проблем в написании аналога VLA вручную на языках ассемблера (например на известных мне i8080, x86-32, x86-64, ARM).

SZT ★★★★★
() автор топика
Ответ на: комментарий от SZT

Только там непонятно, с какой конкретно версией стандарта C идет сравнение совместимости

См. список Normative References на стр. 1 (арабская, стр. 16 по счёту с начала). C99.

Например в новых стандартах C есть массивы, размер которых можно задать через переменную, при этом программа выделит нужное место на стеке. В плюсах этого нет

В черновике, который ты читаешь, VLA есть, см. стр. 185 (200 по счёту с начала). Из финальной версии стандарта они были удалены.

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 1)
Ответ на: комментарий от proud_anon

В более новом черновике VLA уже нет http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf стр. 212

Тем не менее там в Annex C1 не написано про отсутствие в плюсах VLA. Где скачать финальный стандарт плюсов не за деньги я не нашел

SZT ★★★★★
() автор топика
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от Iron_Bug

он ещё включает передачу параметров только через стек и в определённом «сишном» порядке.

Глупости. Это зависит от реализаци (ABI) и обычно CC для С и С++ ф-ий одинаковые.

mashina ★★★★★
()
Последнее исправление: mashina (всего исправлений: 1)
Ответ на: комментарий от Pavval

А проблем у VLA хватает - типа stack overflow без возможности обработки

Эта проблема существует и для обычных массивов с константным размером. VLA тут ничего нового не добавляют.

mashina ★★★★★
()
Ответ на: комментарий от Iron_Bug

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

Самый грамотный ответ, топик можно закрывать. Нет, правда.

zekka
()
Ответ на: комментарий от mashina

Эта проблема существует и для обычных массивов с константным размером. VLA тут ничего нового не добавляют.

Еще как добавляют. Если массив не предвыделяется, а выделяется по размеру данных, то с предлагаемой реализацией в С++ (очевидно - куча) проблем не возникнет. А с VLA можно приложение грохнуть.

Pavval ★★★★★
()
Ответ на: комментарий от SZT

Блин, хватит читать черновики! Они потому и черновики, а не стандарт, что они никому ничего не должны.

Pavval ★★★★★
()
Ответ на: комментарий от SZT

Тем не менее там в Annex C1 не написано про отсутствие в плюсах VLA

VLA в Си++ нет.

tailgunner ★★★★★
()
Ответ на: комментарий от SZT

Не вижу никаких проблем в написании аналога VLA вручную на языках ассемблера

Не видь дальше, но именно из-за этого его и выпилили как обязательную фичу.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Еще как добавляют ... А с VLA можно приложение грохнуть.

Ну расскажи уж тогда как можешь грохнуть его с VLA так чтобы нельзя было аналогично сделать на обычных массивах.

mashina ★★★★★
()
Ответ на: комментарий от mashina

так чтобы нельзя было аналогично сделать на обычных массивах

Если ты не понял, VLA - функциональный аналог массива в куче, а не стекового.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

VLA - функциональный аналог массива в куче, а не стекового

Херасе.

tailgunner ★★★★★
()
Ответ на: комментарий от Pavval

Если ты не понял, VLA - функциональный аналог массива в куче, а не стекового.

Какая разница как ты для себя определяешь VLA, покажи просто пример.

mashina ★★★★★
()
Ответ на: комментарий от ilammy

Обычными массивами можно связный список нужного размера на стеке выделить через рекурсию, но это будет жуткий костыль и говнокод. А так вообще, очевидная альтернатива(аналог) VLA - alloca()

SZT ★★★★★
() автор топика
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от ilammy

Я тут еще подумал. Через определенные костыли можно и без alloca() сделать аналог VLA на C, но это будет уже полный аут

SZT ★★★★★
() автор топика
Ответ на: комментарий от ilammy

Очевидно же...

Этот пример неправильный, аналогично можно сделать с массивом константного размера, это не особенность VLA.

mashina ★★★★★
()
Ответ на: комментарий от mashina

у компиляторов для разных языков разные методы формирования и передачи параметров. и это не обязательно С/C++. обычно компилятор предоставляет несколько вариантов, для совместимости с другими языками и cdecl - один из самых распространённых и принятых для взаимодействия модулей, написанных на разных языках.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Iron_Bug

у компиляторов для разных языков разные методы формирования и передачи параметров. и это не обязательно С/C++

СС не является частью C/C++, это платформозависимо. cdecl это не обязательный CC для С кода, потому и extern «C» по факту незачем делать CC отличным от C++ вызовов. Нужно ли ещё раз объяснять это другими словами?

... и cdecl - один из самых распространённых и принятых для взаимодействия модулей, написанных на разных языках.

Это было на x86_32 платформах, сейчас (на amd64, армах и т.д. в онтопиках) cdecl давно уже не используется. С разморозкой.

mashina ★★★★★
()
Ответ на: комментарий от mashina

не надо мне комментариев для детсада. у меня опыт системного программирования с 2000 года. я дрова пишу под разные системы и ядра собираю много лет. в том числе и для разных архитектур. 64 бита в эмбеддедах - редкость. и это точно не те архитектуры, под которые есть только С компилятор.

Iron_Bug ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.