Кросс-платформенные различия в C-программах на Windows и Unix OS - PullRequest
11 голосов
/ 19 февраля 2010

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

Ответы [ 9 ]

15 голосов
/ 19 февраля 2010

Подобные проблемы обычно возникают, когда вы не придерживаетесь стандартного C и делаете предположения об окружающей среде, которые могут быть неверными. Это может включать в себя:

  • нестандартный, в зависимости от платформы (<conio.h>, <windows.h>, <unistd.h>, ...);
  • неопределенное поведение (fflush(stdin), как сообщал кто-то другой, по стандарту не требуется ничего делать - это фактически неопределенное поведение - вызывать fflush для чего угодно, кроме потоков вывода; в общем, старые компиляторы были более снисходительны в отношении нарушения некоторых тонких правил, таких как строгое псевдонимы, так что будьте осторожны с «умными» приемами указателя);
  • размер типа данных (short = 16 бит, int = long = 32-битное допущение не распространяется везде - например, 64-битный Linux имеет 64-битный long);
  • в частности, размер указателя (void * не всегда 32-битный и не всегда может быть безопасно приведен к unsigned long); в общем, вы должны быть осторожны с преобразованиями и сравнениями, которые включают указатели, и вы всегда должны использовать предоставленные типы для задач такого типа вместо «обычных» int s (см., в частности, size_t, ptrdiff_t, uintptr_t)
  • тип данных "внутренний формат" (в стандарте не говорится, что float s и double s в IEEE 754, хотя я никогда не видел, чтобы платформы делали это по-другому);
  • нестандартные функции (__beginthread, функции безопасных строк MS; с другой стороны, расширения POSIX / GNU)
  • расширения компилятора (__inline, __declspec, #pragma s, ...) и вообще все, что начинается с двойного подчеркивания (или даже с одного подчеркивания, в старых, нестандартных реализациях);
  • коды консоли (обычно это проблема при попытке запустить код Unix в Windows);
  • формат возврата каретки: в обычных строках он \n везде, но при записи в файл он \n на * NIX, \r\n на Windows, \r на Mac с пред-OSX; преобразование выполняется автоматически с помощью файловых потоков, поэтому будьте осторожны, чтобы открывать файлы в двоичном формате , если вы действительно хотите записать двоичные данные , и оставлять их в текстовом режиме, когда хотите записать текст.

В любом случае, пример программы, которая не компилируется в * NIX, будет полезен, мы можем дать вам более точные предложения.

Подробности о программе еще не получены. Студенты были из нашей предыдущей партии. Попросили об этом. Turbo C - это то, что используется в настоящее время.

Как сказано в комментарии, пожалуйста, отбросьте Turbo C и (если вы используете его) Turbo C ++, в настоящее время они оба являются историческими элементами и имеют много несовместимостей с текущими стандартами C и C ++ (и если Я хорошо помню, что они оба генерируют 16-битные исполняемые файлы, которые даже не работают в 64-битных ОС на x86_64).

Существует множество бесплатных, работающих и совместимых со стандартами альтернатив (VC ++ Express, MinGW, Pelles C, CygWin для Windows и gcc / g ++ - это стандарт де-факто для Linux, конкурирующий с clang), у вас просто есть выбрать один.

10 голосов
/ 19 февраля 2010

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

5 голосов
/ 19 февраля 2010

Стандартные библиотеки, которые поставляются с MSVC, и библиотеки, которые поставляются с типичным компилятором Linux или Unix, достаточно различаются, чтобы вы могли столкнуться с проблемами совместимости. Могут также быть небольшие диалектические различия между MSVC и GCC.

Самый простой способ протестировать ваши примеры в среде, подобной Unix, - это установить Cygwin или MSYS в существующий комплект Windows. Они основаны на GCC и общих библиотеках с открытым исходным кодом и будут вести себя гораздо больше как среда компилятора C в системах Unix или Linux.

  • Cygwin наиболее похож на Unix и основан на cygwin.dll, который является уровнем эмуляции, который эмулирует системные вызовы Unix поверх родного Win32 API. Обычно все, что компилируется в Cygwin, очень вероятно компилируется в Linux, так как Cygwin основан на gcc и glibc. Однако собственные API-интерфейсы Win32 недоступны для приложений, скомпилированных в Cygwin.

  • MSYS / MinGW32 предназначен для создания собственных приложений Win32 с использованием GCC. Однако большинство стандартных библиотек GNU и других OSS доступны, поэтому они ведут себя больше как среда Unix, чем VC. Фактически, если вы работаете с кодом, который не использует Win32 или Unix-специфичные API, он, вероятно, будет легче переносить между MinGW32 и Linux, чем между MinGW32 и MSVC.

Хотя установка Linux в вашей лаборатории, вероятно, полезная вещь (используйте проигрыватель VMWare или другой гипервизор, если вы не можете получить финансирование для новых серверов), вы можете использовать любой из перечисленных выше наборов инструментов, чтобы получить что-то, что, вероятно, быть «достаточно близко» для ваших целей. Вы можете изучать Unix так, как вам нравится, и Cygwin, и MSYS предоставят вам среду, похожую на Unix, которая может дать вам небольшое введение в то же время.

2 голосов
/ 19 февраля 2010

Есть эта вещь, которая называется Анси С . Пока вы кодируете чисто Ansi C, не должно быть никакой разницы. Однако это довольно академическое предположение.

В реальной жизни я никогда не сталкивался ни с одним из моих кодов, переносимых с Linux на Windows и наоборот, без каких-либо изменений. На самом деле, эта модификация S (определенно во множественном числе) превратилась в огромное количество директив препроцессора, таких как #ifdef WINDOWS ... #endif и #ifdef UNIX ... #endif ... даже больше, если некоторые параллельные библиотеки, такие как OPENMPI были использованы.

Как вы можете себе представить, это полностью противоречит читаемому и отлаживаемому коду, но это было то, что сработало; -)

Кроме того, вы должны учесть уже упомянутые вещи: UTF-8 иногда отключает компиляторы Linux ...

2 голосов
/ 19 февраля 2010
Синтаксис

C должен быть одинаковым, если компиляторы Windows и Unix придерживаются одного и того же стандарта C.Мне сказали, что компиляторы MS по-прежнему не поддерживают полностью C99, хотя компиляторы Unix работают достаточно быстро, поэтому кажется, что C89 является наименьшим общим знаменателем.

Однако в мире Unix вы обычно используете системные вызовы POSIXделать системные вещи, такие как IPC и т. д. Windows не является системой POSIX, поэтому у нее есть другой API для нее.

1 голос
/ 19 февраля 2010

Думаю, очень важно, чтобы вы прямо сейчас ознакомились с Unix.

Отличный способ сделать это с Knoppix CD.

Попробуйте скомпилировать свои программы под Linux, используя gc, и, если они не работают, отследите проблемы (#include ?) И заставьте его работать. Затем вернитесь в Windows, и он, вероятно, скомпилируется нормально.

Таким образом, вы обнаружите, что ваши программы становятся чище и лучше для учебного материала, даже для лабораторных упражнений на компьютерах с Windows.

1 голос
/ 19 февраля 2010

Сам язык C является переносимым с Windows на Unix. Но детали операционной системы разные, и иногда они вторгаются в ваш код.

Например, системы Unix обычно используют только «\ n» для разделения строк в текстовом файле, в то время как большинство инструментов Windows ожидают увидеть «\ r \ n». Существуют способы справиться с подобными различиями таким образом, чтобы среда исполнения C могла справиться за вас, но если вы не будете осторожны, вы знаете о них, то довольно просто написать специфический для ОС код C.

Я мог бы, чтобы вы запустили Unix на виртуальной машине и использовали его для проверки своего кода перед тем, как поделиться им со своими учениками.

1 голос
/ 19 февраля 2010

Не должно быть никакой разницы между языком программирования C под windows или * nix, поскольку язык определяется стандартом ISO.

0 голосов
/ 19 февраля 2010

Общая проблема в том, что fflush(stdin) не работает в Unix.Что совершенно нормально, так как стандарт не определяет, как реализация должна его обрабатывать.Решение состоит в том, чтобы использовать что-то вроде этого (не проверено):

do
{
    int c = getchar();
}
while (c != '\n' && c != EOF);

Аналогично, вам нужно избегать всего, что вызывает неопределенное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...