C程序在Windows和Unix OS上跨平台差异

时间:2010-02-19 09:06:33

标签: c windows unix cross-platform

用Windows和Unix编写的C有什么区别吗? 我教C和C ++,但我的一些学生回来说,一些示例程序不能在Unix中运行它们。 Unix对我来说很陌生。不幸的是没有任何经验。我所知道的就是拼写它。如果有任何差异,那么我应该建议我们的部门投资Unix系统,因为目前我们实验室中没有Unix系统。我不希望我的学生觉得他们被拒绝或远离某些东西。

9 个答案:

答案 0 :(得分:15)

当您不遵守裸C标准时,通常会出现这种问题,并对可能不正确的环境做出假设。这些可能包括依赖:

  • 非标准,平台特定包括(<conio.h><windows.h><unistd.h>,...);
  • 未定义的行为(fflush(stdin),正如其他人所报告的那样,不需要按标准执行任何操作 - 实际上未定义的行为是对除输出流之外的任何内容调用fflush;通常,较旧的编译器是违反一些细微规则,如严格别名,更加宽容,所以要小心“聪明”指针技巧);
  • 数据类型大小(short = 16位,int = long = 32位假设并不存在 - 例如,64位Linux有64位{{ 1}});
  • 特别是,指针大小(long并不总是32位,并且不能总是安全地转换为void *);一般来说,你应该注意涉及指针的转换和比较,你应该总是使用提供的类型来代替“普通”unsigned long s(特别参见int,{{ 1}},size_t
  • 数据类型“内部格式”(标准并未说ptrdiff_tuintptr_t在IEEE 754中,尽管我从未见过平台做不同的事情);
  • 非标准函数(float,MS安全字符串函数;另一方面,POSIX / GNU扩展)
  • 编译器扩展程序(double__beginthread__inline s,...)以及通常以双下划线开头的任何内容(或者甚至是单个下划线,旧的,非标准的)实现方式);
  • 控制台转义码(当您尝试在Windows上运行Unix代码时,这通常是个问题);
  • 回车格式:在普通字符串中它到处都是__declspec,但是当在文件上写入时它是* {NIX上的#pragma\n在Windows上,\n在OSX之前Mac电脑;转换是由文件流自动处理的,因此当你想要写二进制数据时要小心打开二进制文件中的文件,并在你想要写文本时将它们留在文本模式中。

无论如何,一个不在* NIX上编译的程序示例会有所帮助,我们可以为您提供精确的建议。

该计划的详细信息尚未获得。这些学生来自我们之前的批次。已经要求了。 turbo C是目前正在使用的。

如评论中所述,请删除Turbo C 和(如果您使用它)Turbo C ++,现在它们都是历史记录,并且与当前的C和C ++标准有许多不兼容性(和如果我记得很清楚,他们都会生成16位可执行文件,甚至不能在x86_64上运行64位操作系统。)

有许多免费,工作和标准兼容的替代品(VC ++ Express,MinGW,Pelles C,CygWin在Windows上,而gcc / g ++是Linux上的事实标准,可与clang相媲美),你只需拥有选一个。

答案 1 :(得分:10)

语言是相同的,但用于获取任何特定于平台的任何库都是不同的。但是,如果您正在教C(而不是系统编程),您应该能够轻松编写可移植代码。您没有这样做的事实让我对您的培训材料质量感到疑惑。

答案 2 :(得分:5)

MSVC附带的标准库以及典型的Linux或Unix编译器附带的标准库与您可能遇到的兼容性问题不同。 MSVC和GCC之间也可能存在微小的辩证变异。

在类似unix的环境中测试示例的最简单方法是在现有的Windows工具包上安装Cygwin或MSYS。它们基于GCC和常见的开源库,其行为更像是unix或linux系统上的C编译器环境。

  • Cygwin是'unix like',它基于cygwin.dll,它是一个模拟层,可以在本机Win32 API之上模拟unix系统调用。通常,在Cygwin上编译的任何内容都很可能在Linux上编译,因为Cygwin基于gcc和glibc。但是,在Cygwin上编译的应用程序无法使用本机Win32 API。

  • MSYS / MinGW32旨在使用GCC生成原生Win32应用程序。但是,大多数标准GNU和其他OSS库都可用,因此它的行为更像是unix环境而不是VC。实际上,如果您正在使用不使用Win32或unix特定API的代码,它可能比MinGW32和MSVC之间更容易在MinGW32和Linux之间移植。

虽然在您的实验室中安装Linux可能是一件有用的事情(如果您无法获得新服务器的资金,请使用VMWare播放器或其他一些虚拟机管理程序),您可以使用上述任一工具链来获取可能的内容为你的目的“足够接近”。你可以学习unix作为你的想象,Cygwin和MSYS都会给你一个类似unix的环境,在此期间可以给你一点温和的介绍。

答案 3 :(得分:2)

如果Windows和Unix编译器都遵循相同的C标准,则

C语法必须相同。我被告知MS编译器仍然不完全支持C99,虽然Unix编译器速度很快,所以看起来C89是最低的共同点。

然而在Unix世界中,您通常会使用POSIX系统调用来执行系统操作,例如IPC等.Windows不是POSIX系统,因此它具有不同的API。

答案 4 :(得分:2)

有一个名为Ansi C的东西。只要您编写纯粹的Ansi C代码,就没有区别。然而,这是一个相当学术的假设。

在现实生活中,我从未遇到任何代码可以从Linux移植到Windows,反之亦然,没有任何修改。实际上,这个修改 S (绝对是复数)变成了大量的预处理器指令,例如#ifdef WINDOWS ... #endif#ifdef UNIX ... #endif ...甚至更多,如果有些并行使用了诸如OPENMPI之类的库。

正如您可能想象的那样,这与可读和可调试的代码完全相反,但这是有效的; - )

此外,你必须考虑已经提到的事情:UTF-8有时会淘汰linux编译器...

答案 5 :(得分:1)

在Windows或* nix下,C编程语言之间应该没有区别,因为语言是由ISO标准指定的。

答案 6 :(得分:1)

C语言本身是从Windows到Unix的可移植版本。但操作系统的详细信息不同,有时会侵入您的代码。

例如,Unix系统通常只使用“\ n”来分隔文本文件中的行,而大多数Windows工具都希望看到“\ r \ n”。有一些方法可以解决这种差异,让C运行时为你处理它,但如果你不小心了解它们,那么编写特定于操作系统的C代码就很容易了。

我可以在虚拟机中运行Unix,并在与学生分享代码之前使用它来测试代码。

答案 7 :(得分:1)

我认为你现在熟悉unix是至关重要的。

执行此操作的最佳方法是使用Knoppix CD。

尝试使用gc在Linux下编译程序,当它们不起作用时,跟踪问题(#include&lt; windows&gt;?)并使其正常工作。然后返回到窗口,它可能编译好。

通过这种方式,即使是在Windows机器上进行实验练习,您也会发现您的课程变得更加清晰,教学材料更加完善。

答案 8 :(得分:0)

一个常见问题是fflush(stdin)在Unix上不起作用。 这是完全正常的,因为标准没有定义实现应该如何处理它。 解决方案是使用类似的东西(未经测试):

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

同样,您需要避免任何导致未定义行为的事情。