2009-08-10 7 views
5

Я предполагаю, что большинство компиляторов C++ записаны в сборке. Что делает их разными языками полностью (я мог ошибаться). Если я собираюсь создать функцию стиля cout для обычного старого C, как бы я это сделал? cout имеет некоторые очень впечатляющие возможности принять этот фрагмент, например:Создание функции cout в C?

// endl not only prints a new line but also flushes the stream 
cout << "Hello World!" << endl; 

Что я уверен, что переводит это в C:

printf("Hello World!\n"); 
fflush(1);     //stdout = 1 

Следующий заказ бизнеса, << операторов. В C++ это было бы легко (перегрузка оператора), но я не могу придумать ни одного способа сделать это в C.

+2

Не уверен, с чего начать на этом ... Короткий ответ в том, что C++ язык определяется так, чтобы синтаксис был подобным, а язык C - нет. - Но ваш вопрос можно взять из «Как написать компилятор для языка C-расширения?» вплоть до «Как дублировать функции iostream в пользовательской библиотеке с макросами C-стиля для специального синтаксиса?» –

+0

@ Конкурирующий компилятор: Я знаю, что вы говорите. Вот почему я назвал это гипотетическим. Это не важно ... Мне просто интересно. – Kredns

+4

Большинство компиляторов C++ написаны на C или C++ - и не в сборке. –

ответ

5

Это верно, потому что C не имеет перегрузки оператора, вы не можете изменить поведение < <, он всегда будет немного смещаться, поэтому нет способа написать «cout» с точной семантикой, которую он имеет в C++, в C.

Из интереса g ++ (компилятор GNU C++) написан в основном in C.

4

C на самом деле является популярным языком реализации для компиляторов C++ и стандартных библиотек (так же, как и сам C++, понятие, которое иногда называют самообслуживанием или самонастраиванием языка), и вы можете изучите все источники богатой, сложной стандартной библиотеки C++ (плюс расширения) here (извините, это gcc 3 - не удается найти исходное дерево gcc 4, которое так же легко просматривается в Интернете, хотя, конечно, вы можете легко загрузить эти источников и изучить их на вашей локальной машине).

Лично я бы предложил начать с хорошей книги, такой как this one - источники будут намного более значимыми для вас, как только у вас будет хорошее понимание всех неясных укромных уголков и искажений iostreams C++ (as бонус, книга также проведет вас на экскурсию по локалям - держитесь за свою шляпу! -).

8

Это может помочь подумать об этом, чтобы перевести между синтаксисом оператора «< <» и «оператором < <» синтаксисом функции. Ваш C++ пример эквивалентен этому фрагменту кода C++:

operator<< (operator<< (cout, "Hello World!"), endl); 

Первое, что вы должны заметить здесь, что есть на самом деле не много сообразительности в соиЬ вообще. Что является умным оператором < < Функция - в частности, версия оператора < < Функция, которая берет объект потока (что и есть cout, но многие другие вещи тоже) в качестве первого аргумента. Или, точнее, диапазон операторов < <, которые принимают объект потока в качестве первого аргумента, и берут конкретную вещь в качестве второго аргумента - для каждого типа объектов, который можно поместить в поток cout, есть один. Вы также можете увидеть один из трюков C++ в этом синтаксисе; оператор < < функции на объектах потока всегда возвращают объект потока, который они были заданы, тем самым обеспечивая цепочку такого рода.

Чтобы добавить код C++ в компоновщики и системные ABI, которые ожидают синтаксиса функции C-like, большинство компиляторов C++ «изменят» имена функций, чтобы кодировать в них тип аргументов, которые у них есть. (Также, конечно, «< <» не является допустимым именем функции C-типа.) Итак, если вы посмотрите на сгенерированную сборку для этого бита функции, вы увидите, что имена этих двух функций были отличные друг от друга - у них были бы суффиксы, указывающие типы аргументов.Вы могли бы сделать что-то подобное вручную:

operator_lshift__stream__endl(
    operator_lshift__stream__string(cout, "Hello World!"), endl); 

И у вас есть что-то, что вы могли бы реализовать в С.