Обзор C/C++ компиляторов EMX и Watcom
В предлагаемой статье описывается мое видение некоторых компиляторов С/C++ под OS/2. Должен сразу оговориться, что не претендую ни на полноту изложения, ни на энциклопедическую точность; это, скорее, просто ощущения и впечатления, разбавленные общеизвестными фактами, а где-то и наоборот. Где-то изложение может показаться претенциозным, но это во всяком случае не нарочно - больше от вероятного незнания мной некоторых фактов.
Watcom C/C++
Watcom - звезда прошлого. Основные черты - многоплатформенность и качество кода. В лучшие времена генерировал код для DOS real mode, DOS protected mode (DOS/4G, DOS/4GW, Phar Lap), Win16, Win32, Win32s, QNX, OS/2 (16- & 32-bit), Netware NLM. Причем, работая под любой системой, можно было генерировать код для всех остальных (к примеру, программу под Win32 можно было скомпилировать и слинковать из-под OS/2 и т.д.). Watcom стал весьма популярен во времена DOS-игр, работающих в защищенном режиме (DOOM и пр.).
К моменту появления версии 11.0 (1997 г.) фирма, разрабатывавшая Watcom, была куплена Sybase Inc., и это, к сожалению, возвестило о кончине компилятора. Дальнейшая разработка была практически заморожена, а в 1999 г. Sybase Inc. объявила о прекращении продаж и установила крайний срок, после которого будет прекращена и техническая поддержка для тех, кто еще успел купить компилятор (это было 30 июня 2000 г.). Дальнейшая судьба продукта пока неизвестна.
Последняя версия - 11.0B. C++ компилятор в ней не поддерживает namespaces и не содержит STL. Впрочем, существуют многие реализации STL, поддерживающие Watcom C++ (к примеру, STLPort ).
Под любую поддерживаемую систему есть набор стандартных утилит: компиляторы, линкер, отладчик(и), make, lib, strip и пр. В системах с GUI (OS/2, Windows) есть также IDE (хотя и не очень удобная).
Кодогенерация застыла на уровне 1997 г., и теперь даже MS Visual C++ обгоняет Watcom (естественно, сравнения проводились под Windows, но некоторое представление это дать может).
При работе с Watcom C++ под OS/2 нужно знать следующее:
- В версиях 11.0* в линкере есть досадная ошибка, и вызовы 16-разрядных функций OS/2 (Vio*, Kbd*, Mou* и др.) будут давать трапы. Для борьбы с этим предназначена утилита LXFix, которая запускается после линкера и исправляет fixups.
- В комплект входит весьма древний OS/2 Toolkit (от OS/2 2.x). Поэтому крайне рекомендуется установить Toolkit из последних (4.0, 4.5).
- Кроме разработки "родных" OS/2-программ, Watcom C/C++ можно рекомендовать для компиляции кода, слабо привязанного к ОС. Наличие в стандартной библиотеке функций вроде _dos_setdrive(), поддерживаемых под всеми системами (ну, или как минимум под OS/2, Win32 и DOS) позволяет писать в этом смысле платформонезависимо (для пользовательского интерфейса в данном случае можно использовать Turbo Vision).
И напоследок стоит еще раз напомнить про то, что компилятор более не развивается и не поддерживается. Имеющиеся проблемы никуда не денутся и не будут теперь решены.
Ссылки:
- Домашняя страница продукта
- Newsgroup поддержки (Fidonet echoarea WATCOM.C)
EMX (GNU C/C++)
EMX - представительство Unix в OS/2 и одно из представительств Unix в DOS. Это целый комплект из компиляторов, сопутствующих утилит и библиотек поддержки. В первую очередь предназначен для портирования программ из среды Unix в OS/2, для чего эмулирует множество функций в "первозданном" виде, включая даже и fork(). Основывается на одном из наибольших достижений мира бесплатных программ - системе компиляторов GCC (gcc означает "GNU Compiler Collection"). GCC состоит из собственно трансляторов с языков программирования (в настоящее время это C, C++, Objective C, Fortran 77, Chill и Java, хотя ничто не мешает встроить в систему свой язык), превращающих исходный код в программу на внутреннем языке компилятора (он называется RTL - Register Transfer Language) и стартующих уже от представления на RTL генераторов машинного кода для различных платформ. В частности, поддерживается и нужная нам платформа i386.
Сам EMX является портом GCC под OS/2 / DOS и содержит измененные версии компиляторов, линкера, отладчика gdb и многих других программ; стандартную библиотеку C, содержащую множество функций из мира Unix; DLL поддержки и многое другое. Кроме того, с помощью EMX под OS/2 были скомпилированы многие другие Unix-программы, к примеру GNU Make, который обязательно понадобится при мало-мальски серьезной разработке.
Кроме всего прочего, EMX позволяет создавать "родные" программы для OS/2, используя OS/2 API. Можно также использовать в программах одновременно и "родные", и "заимствованные" функции.
Программы же, не использующие OS/2 API и некоторых функций Unix, будут "контрабандой" работать и из-под голого DOS во flat mode (в комплекте с EMX поставляется DOS-расширитель). К тому же, и под Windows есть расширитель rsx.exe, позволяющий запускать файлы в формате a.out, сгенерированные EMX!
Но сам GCC родом из мира Unix, и поэтому EMX также привносит с собой кое-что оттуда. Вот основные моменты:
- Прямой слэш ('/'). Как известно, в Unix для разделения каталогов в файловом пути вместо обратных слэшей используются прямые. Нет, все стандартные функции (open(), fopen() и др.) понимают оба варианта, но вот при указании файлов и путей компилятору придется использовать прямые. (Не пугайтесь, c:/aaa/bbb/ccc это нормально :-)
- Нестандартные форматы файлов. Да, объектные файлы имеют расширение .o и формат a.out, отличный от привычных .obj-файлов. То же самое верно и для файлов объектных библиотек (.a в сравнении с .lib). И даже исполняемые файлы фактически являются файлами формата a.out, содержащими пришпиленный в начале LX-загрузчик.
Но это еще не все. Существует возможность делать и .obj файлы, и нормальные LX .exe (для этого вызываются всяческие конверторы и на финальном этапе link386). Все эти многочисленные варианты (еще отметим широкие возможности по созданию различных типов DLL) разнятся предоставляемыми возможностями. К примеру, если работать с .obj и LX .exe, то программа не будет запускаться под DOS и ее нельзя будет отлаживать. Если к тому же выбрать статическую линковку, то еще и список поддерживаемых функций уменьшится. В общем, есть простор для экспериментирования (хотя наиболее часто используемый вариант - a.out формат исполняемого файла + динамическая линковка с EMX runtime).
- Расширения C, C++. Не будем их здесь перечислять, отметим лишь, что они есть и что их применение делает программу непереносимой.
- Компиляция всегда идет через ассемблер. Т.е. кодогенераторы генерируют лишь ассемблерный текст и переваливают проблему на плечи ассемблера. Не стоит пугаться, с ней он справляется весьма быстро. К тому же, существуют возможности:
- всем частям компилятора общаться друг между другом с помощью pipes (выход препроцессора поступает сразу на вход компилятору, а выход последнего ассемблеру) и обойтись без временных файлов.
- всем частям компилятора висеть некоторое время в памяти после последнего обращения и тем самым экономить время на их запуске.
- Нестандартная библиотека. Работавшие с какими-либо другими компиляторами могут не найти привычных функций, зато могут найти множество других, доселе неизвестных. :-) Но основное отличие EMX от остальных - это объединение хендлов файлов и сокетов в одну группу. К примеру, используя EMX, не нужно вызывать sock_init(), можно использовать read() и write(), а задачу soclose() выполняет обычный close(). Кроме этого, функция select(), работающая в IBM TCP/IP только для сокетов, в EMX расширена до поддержки любых хендлов, как и полагается в Unix'e. :-)
Как уже отмечалось выше, GCC распространяется под лицензией GNU. Разработка GCC, инициированная где-то в конце 80-х гг. - начале 90-х гг., поначалу велась командой разработчиков, возглавлявшейся идеологом GNU Ричардом М. Столлменом (rms); в 1996 г. ими была выпущена версия 2.7.2.1 и затем экспериментальная версия 2.8.1. Если поддержка C в последней была на уровне ANSI C + расширения (см. выше), то ситуация с C++ была тяжелой; к тому же, разработка фактически остановилась. Но еще до выпуска 2.8.1 за развитие GCC взялась фирма Cygnus, особенно направив свои усилия на выправление ситуации с C++ (к тому времени до принятия стандарта C++ оставалось не так уж и много). Эта фирма выпустила несколько версий EGCS (Enhanced GNU Compiler Suite), после чего Столлмен и компания решили и вовсе их благословить. Развитие версии 2.8.1, содержавшей кучу ошибок в реализации C++, было заброшено, последняя к тому времени версия EGCS автоматически превратилась в последнюю версию GCC (2.95), а развитие GCC фактически продолжилось командой из Cygnus. Последняя выпущенная ими версия - 2.95.2, это случилось 27 октября 1999 г. (А сама Cygnus не так давно была приобретена небезызвестной компанией Red Hat Inc.)
Последняя версия GCC довольно близка к стандарту, поддерживает все последние добавления к C++ (вроде namespace) и включает в себя также реализацию STL от SGI (она включена в libstdc++, последняя версия 2.90.8). STL из libstdc++ близка к стандарту, но iostreams там все еще не template-based, а взяты из совсем старой libg++. Впрочем, можно опять же обратиться к STLport , она поддерживает и GCC.
Таково состояние GCC на сегодняшний момент. Однако, использовать GCC под OS/2 означает использовать EMX, последняя версия которого (v0.9d) включает в себя старый GCC 2.8.1. Но все не так плохо. Ибо есть еще проект под названием PGCC, суть Pentium-optimized GCC. Сам GCC хоть и содержит различные оптимизации для базовой платформы i386, но про особенности конкретных процессоров современности (а это кроме различных вариантов Pentium еще и Cyrix, AMD, все сильно отличающиеся друг от друга по тому, как надо для них оптимизировать) знает крайне мало. Цель проекта PGCC - научить GCC генерировать программы, выжимающие максимум из процессора. (PGCC - это набор "патчей" к GCC). А что самое приятное, в команде PGCC есть Андрей Заболотный (автор lxlite), кроме всего прочего компилирующий релизы PGCC для OS/2. Последний PGCC - 2.95.3, основан на GCC 2.95.2. Оптимизация для конкретного процессора производится при указании определенного ключа в командной строке, так что если его не указывать, то мы получаем "честный" GCC 2.95.2, со всеми его прелестями.
А теперь о прелестях применительно к OS/2. Сам компилятор версии 2.95.2 уже вполне неплох. Он параноидален в духе последнего стандарта (по моим субъективным ощущениям предупреждений об ошибках в сравнении с версией EGCS 1.1.2 стало раза в два больше), не падает, генерирует приемлемый код. Смелые могут даже поставить ключ '-O6' и попробовать оптимизацию под Pentium (здесь имеется в виду PGCC). Но про нормальную отладку PM-приложений можно сразу же забыть. Нацеленный на это PMGDB, входящий в состав EMX, крайне примитивен, да и порой просто не работает (у меня на Авроре при выходе попросту виснет и приходится срубать его по kill -9). То же самое с profiling (поддержка заявлена, но опять же на Авроре виснет намертво, до reset). EMX runtime версии до 0.9d FIX 2 не работал на Авроре, а равно и любая программа, его использовавшая. Проблемы могут явиться сами собой (к примеру, у меня PrfOpenProfile("test.ini", ...) давал трап до тех пор, пока через пару месяцев не догадался поставить ключ '-fwritable-strings'). Короче говоря, будьте готовы к возникновению странных проблем и к дубовой отладке.
Компиляторы GCC (C и C++), как уже говорилось выше, можно рекомендовать для переноса программ из Unix под OS/2. Впрочем, как раз в этой области весьма мало вариантов, если не сказать, что как раз один. Можно наоборот, с помощью EMX разрабатывать программы, которые потом будут работать под Unix. Правда, к сожалению, многие функции не поддерживаются EMX. Как минимум, нет очередей сообщений, семафоров, shared memory (ни BSD, ни POSIX). Здесь стоит также заметить, что порты GCC существуют и под win32, и под DOS (а еще вспомним про возможность запуска a.out-программ, сделанных EMX, под DOS и win32!), так что теоретически с помощью EMX можно писать программы, которые будут компилироваться и работать под OS/2, Unix, DOS и Windows.
Главное же достоинство EMX - он абсолютно бесплатен и доступен в исходных текстах. А если вы не верите, что он работает, вот доказательство: такая большая вещь, как XFree86, компилируется с помощью EMX и работает под OS/2! Не говоря о многих других программах меньшего размера.
Ссылки:
Если у вас есть замечания, предложения или дополнения к этому материалу - пишите.
Оставить комментарий
Оставлять комментарии могут только зарегистрированные пользователи.
Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.
Комментарии
1. -=Prog=- / 22 апреля 2009, 06:59:24

юра я так понимаю ты хотел написать вот это

#include <stdio.h>
#include <conio.h>
void main()
{
int c, nb, nt, nl;
nb = 0;
nt = 0;
nl = 0;
printf("programa podscheta simvolov\ndlya vixoda nazhmite <Ctrl>+<Z>\n");
while((c = getchar()) != EOF)
{
if (c==' ')
++nb;
else if (c=='\t')
++nt;
else if (c=='\n')
++nl;
}
printf("nanazhatie clavishi\n<Probel> %d\<Tab> %d\n<Enter> %d", nb, nt, nl);
getch();
2. Dominus / 05 августа 2007, 02:35:23

#include <stdio.h>

#include <conio.h>
int main()
{
char c;
int nb, nt, nl;
nb = 0;
nt = 0;
nl = 0;
while((c = getchar()) != 0x71) //при нажатии
//"q" происходит выход из цыкла
{
if (c==' ')
++nb;
else if (c=='t')
++nt;
else if (c=='n')
++nl;
}
printf( "%d %d %dn", nb, nt, nl);
getch();
return 0;
}
3. Супер-пупер-программёр / 11 ноября 2005, 14:21:20

Придурок, кавычку двойную закрой в 11-ой строке


4. alxch / 29 марта 2005, 12:59:42

c у тебя int, а в c=='\t' делается каст в char чтобы удалось сравнить. лучше указать явно либо 

char c,nb,nt,nl
либо if ((char)c=='\t')
5. юра / 23 марта 2005, 17:08:04

ребята помогите где ошыбка

#include <stdio.h>
main()
{
int c, nb, nt, nl;
nb = 0;
nt = 0;
nl = 0;
while((c = getchar()) != EOF)
{
if (c== '')
++nb;
else if (c=='\t')
++nt;
else if (c=='\n')
++nl;
}
printf( "%d %d %d\n", nb, nt, nl);
}
