Поэтому я разрабатываю язык программирования, который компилируется в байт-код для выполнения виртуальной машины, а также в C в качестве промежуточного языка для компиляции в собственный двоичный файл. Я выбрал C, потому что он достаточно низкоуровневый и переносимый, что позволяет сэкономить огромное количество усилий за счет повторного использования существующих компиляторов и отсутствия необходимости писать компиляторы для сборки для каждой отдельной платформы и ее странностей.
Но существующие компиляторы имеют свои недостатки, одним из которых является проблема циклической зависимости. Я хочу решить циклические зависимости элегантным способом (в отличие от C / C ++) без неудобных предварительных объявлений, без необходимости использовать указатели, дополнительную косвенность и бесполезную трату памяти, без необходимости отделять объявления от определений и так далее ... Другими словами, устраните эту проблему от разработчика, как это делают некоторые языки программирования.
На мой взгляд, основная проблема нынешних компиляторов C / C ++ заключается в том, что они не могут «заглядывать в будущее», хотя на самом деле это не будущее, поскольку намерение программиста уже выражено в коде, у моего компилятора такой проблемы нет. , он не знает ничего, кроме определенной точки прогресса синтаксического анализа, он знает размеры объектов с круговыми зависимостями и может вычислять соответствующие смещения и тому подобное.
Я уже реализовал «поддельное» наследование, которое просто выполняет «встроенное расширение» членов унаследованных структур, поэтому я думаю, что могу использовать тот же подход и для фактического поддельного агрегирования. В самом простом и простом примере:
typedef struct {
int a;
} A;
typedef struct {
A a;
int b;
} B;
становится:
typedef struct {
int A_a;
int b;
} B;
и компилятор немного «переводит»:
B b;
b.a.a = 7;
становится:
b.A_a = 7;
Таким же образом все структуры сворачиваются в единую корневую структуру, которая содержит только примитивные типы. Таким образом, в структурах, размеры которых заранее не известны, не используются абсолютно никакие типы, поэтому порядок определения становится неактуальным. Естественно, этот беспорядок скрыт от пользователя и предназначен только для «глаз» компилятора, в то время как пользовательская сторона остается структурированной и читаемой. И само собой разумеется, но двоичный след сохраняется для совместимости с обычным кодом C / C ++, свернутая структура двоично идентична обычной структуре, которая будет использовать агрегацию или наследование.
Итак, мой вопрос: звучит ли это как хорошая идея? Что-нибудь, что может пойти не так, мне не хватает?
РЕДАКТИРОВАТЬ: Я стремлюсь решить проблемы, связанные с C / C ++, с круговыми зависимостями, а не логический парадокс «курица или яйцо». Очевидно, что два объекта не могут содержать друг друга, не создавая бесконечного цикла.
b.A_a
, а не кb.a.a
? Я ожидал, что это будет точно так же, поэтому вы делаете много работы, чтобы что-то оптимизировать без особой выгоды. Просто спрашиваю. - person unwind   schedule 04.11.2013A
иB
были в обратном порядке. Как показано, объявления C хороши, и нет проблем с цикличностью. - person unwind   schedule 04.11.2013A
определяется в терминахB
, аB
одновременно определяется в терминахA
. Я предполагаю, что вместо этого вы пытаетесь выяснить правильный порядок объявления для компилятора C. - person Jonas Bötel   schedule 04.11.2013A_*
членыB
, как если бы это былA
(т. Е. Преобразование его вA*
), у вас будут бесконечные проблемы с выравниванием, заполнением и т.п. - person rodrigo   schedule 04.11.2013#ifdef
s, как в C ++. - person Jonas Bötel   schedule 04.11.2013