C++ как препроцессор в C
А компилятор (если без -O) это препроцессор в ассемблер?
Когда я говорю "С++ - это препроцессор в С" - это значит, что в принципе можно написать программу c++2c.exe и результат ее работы компилировать любым С-компилятором.
При таком подходе вообще не существует компиляторов. Можно написать программу c2asm.exe, которая будет переводить все в ассемблер (причем даже без специфики типа MS/Turbo, а под любой). Это тоже будет препроцессор?
PS Слова компилятор, препроцессор, конвертор, ... я, как-то, не очень различаю
следующая программа:
class MyClass {public: MyClass{} ~MyClass{}};
void FirstFunc
{
какой-то код
try
{
MyClass c1;
какой-то код2;
throw 1;
какой-то код3;
}
catch (...)
{
}
}
преобразуется в следующий c-ишный код:
void FirstFunc
{
какой-то код;
запомним состояние стека (q1);
вызвать функцию MyClass::MyClass;
запомнить, что необходимо вызвать функцию MyClass::~MyClass;
какой-то код2;
//throw 1;
востановить состояние стека q1, вызвав все запомненные функции, которые были после этого состояния
}
ЗЫ: Кстати, про Java на уровне JVM - тут ... хм...
запомним состояние стека (q1);
Радость exception-ов в С++ как раз в том и состоит, что если исключения не происходит, то накладных расходов нет вообще. Этим то они и лучше, чем бесконечные С-шные
if( (ret = f != 0 )
return(ret);
не говоря уж о простоте программирования.
А в том, что на С можно написать интерпретатор обработки исключений, я не сомневаюсь.
При хорошей реализации накладные расходы будут минимальны, а то и вовсе равны.
гон, посмотри дизассемблер
там есть инструкция типа mov fs:xx, чего-то там
это и есть сохранение состояния, а также запись о том, какие деструкторы необходимо будет вызвать
ps
информация о том, какие деструкторы в каком момент надо вызвать, подготавливается на этапе компиляции, в программе на C - это также можно сделать заранее.
там есть инструкция типа mov fs:xx, чего-то там
Вот западло! и впрямь есть... Я думал это только при отладке, чтобы debugger мог раньше моей программы исключения ловить, а нет, даже под release-ом это есть... В gcc правда всего один movl, но все равно есть:
void __attribute__noinline h(void)
{
throw E;
}
void __attribute__noinline f(void)
{
A a;
h;
}
......
.globl _Z1fv
.type _Z1fv, @function
_Z1fv:
.LFB1633:
pushl %ebp
.LCFI6:
movl %esp, %ebp
.LCFI7:
subl $40, %esp
.LCFI8:
movl %ebx, -4(%ebp) ; ВОТ ЭТОТ
.LCFI9:
.LEHB0:
call _Z1hv
......
Странно вообще-то... А почему этот __cxa_throw или как его там не может, глядя на стек, сообразить, в каких обстоятельствах его вызвали, без посторонней помощи. Он правда для этого должен быть не библиотечным, а генерироваться с программой вместе. Я всегда думал, что так и делается...
C++ действительно можно реализовать как препроцессор. Такая штука даже есть(была?) - сfront называется. А exceptions можно реализовать с помощью setjmp/longjmp. Зная стэк до и после exception(те longjmp) можно пройтись по нужной части стэка и вызвать деструкторы). Правда все это довольно медленно. Поэтому создатели cfront в итоге отказались от такого подхода к компилятору.
естественно, можно. Си - язык почти низкого уровняя, и все, что может сделать процессор, можно представить на Си.
и все, что может сделать процессор, можно представить на Си.
Смешно! То что все процессоры, которые ты видел, так сказать, С-совместимы - это следствие лишь популярности С, а не его универсальности. А если в процессоре вообще нет байтов, как его на С программировать? А про Data Flow архитектуры ты слышал? Да просто мультитредовый процессор даже на С программируется не естественно, через какие-нибудь POSIX Threads?...
Не учите меня жить И не придирайтесь к словам. Я сам программирую DSP на интеловских телефонных платах, и, естественно, знаю, что есть и сильно другие архитектуры. Си и Си++ предназначены для одних и тех же процов.
setjmp/longjmp... Правда все это довольно медленно...
Это немного не то. Связка C -> Asm -> Binary транзитивна, то есть результат получится одинаковый, если компилировать поэтапно или сразу. И можно было бы расчитывать на то, что C++ -> C -> Binary тоже будет обладать таким свойством (если конечно оптимизирующие блоки у С++ и у С компиляторов одинаковые). Или ты имеешь в виду "Правда все это довольно медленно [компилируется]"?
Я имел ввиду "медленно работает". Вообще говоря exception handling реально нельзя сделать быстро(как препроцессор). Кстати говоря ранние gcc использовали именно longjmp/setjmp.
Оставить комментарий
rosali
Несколько раз, в том числе и здесь, кажется, слышал мысль, что C++ это всего лишь препроцессор в C. По началу поверил:Но вот сейчас задумался, а на что в С можно отобразить exception handling? Ведь процесс размотки стека, вроде бы, на С невыразим, а он должен быть сгенерирован в соответствии с тем, как этот стек создается. Есть какие-нибудь идеи на тему?