代码之家  ›  专栏  ›  技术社区  ›  drigoSkalWalker

为什么编写可移植的C程序很难?

  •  15
  • drigoSkalWalker  · 技术社区  · 15 年前

    我想知道,为什么要让一个程序在许多操作系统(如Windows和Linux)中运行而不包含粘合代码太难了。它们都共享相同的体系结构(x86),所以我认为应该很简单。此外,C是标准化的,那么为什么在这些操作系统中实现不同呢?为什么很难遵循标准并为所有操作系统实现通用库?

    我已经用C语言编程将近两年了,目前我使用glib实现可移植性。

    我不是在寻找这个问题的解决方案,我已经在为此目的使用glib了。但是我想知道为什么它是必要的,为什么制作一个没有差异的C库是困难的。

    [加]

    例如,当我用C/Glib编写程序时,我使用gchar/gint等类型,实际上是C原语类型,在维基百科关于Glib的文章中,它说:

    为什么C原语类型不能移植到整个语言中?

    10 回复  |  直到 4 年前
        1
  •  28
  •   Matthias Wandel    15 年前

    让您的基本C程序计算一点并打印结果是很容易的。

    问题是,任何做任何实质性工作的C程序都将依赖于来自操作系统的大量服务,而这些服务在许多方面都有所不同。文件I/O趋向于相似,但在图形方面,它们有很大的不同。这就是问题的症结所在。

        2
  •  19
  •   Norman Ramsey    15 年前

    int 使用目标机器的自然字大小(或半字大小)(在那些日子里,PDP-10上可能是18或36位!),而不是目标机器中的位数 int 易于预测,更不用说在所有硬件上都相同了。效率是最重要的考虑因素,尤其重要的是一个程序不能有太多的指令,这样它就可以被塞进一天的小记忆中。例如,没有人愿意在一台16位机器上模拟32位的算术运算,这可能是进行算术运算所需指令数的三倍,从而无法将较大的程序装入内存。

    为什么实现通用库很难?

    一点也不难。问题不在于没有通用图书馆;问题是,人们无法就什么是通用图书馆达成一致。(请参见:GTK、KDE、QT、AT&T U/WIN+AST等等,非常恶心。)但是实现 好的 真正地 坚固的至于为什么很难:图书馆设计只是一个难题,理性的人可以也确实不同意什么是好的设计。因此,多种设计层出不穷,可移植性也随之增加。

    C附带的非常薄的标准库加剧了这种情况。但我们不要忘记,库是在程序员幸运地获得64KB代码和64KB数据的时候设计的。到C++出现的时候,他们可以标准化一个巨大的臃肿的猪,像标准模板库一样。但是当C库被设计时,事情 要小。现在,当标准C库不足以满足当今更雄心勃勃的应用程序时,对于所有C程序员来说,就单一标准达成一致已经太晚了。


        3
  •  16
  •   dmckee --- ex-moderator kitten    15 年前

    如果你坚持核心标准并不难(K&R中的例子通常只需要很少的修正)。但核心标准并不支持人们想做的许多事情。比如:

    • 在文件系统中扎根
    • 比纯流式文本更复杂的IO
    • 请求操作系统访问时钟、打印机和网络
    • 与其他流程对话

    关于原语类型的可移植性: 本标准规定了这些类型的最小尺寸限制,但未规定 真实的 尺寸。大多数平台支持大于最小值的尺寸,但并非所有平台都具有相同的尺寸 相同的 大号的。所以glib和其他跨平台项目定义了它们自己的类型,所以它们只需要 一套 #ifdef 切换以获得正确的大小。

        4
  •  8
  •   Carson Myers    15 年前

    准确的

    基本的文件I/O操作是这样的。

    但是,如果你的代码在系统上的实现方式有一点不同,那么它就不能移植到那个系统上了。

    因此,如果您的代码不涉及任何内容,那么它是可移植的。

    我想这里的主要思想是 最大化 可移植性,因此您可以最大限度地减少必须更改的内容,以便将端口连接到新系统。

        5
  •  4
  •   Nippysaurus    15 年前

    代码是可移植的,但这不是问题所在。

    问题是大多数大型应用程序都使用作为操作系统一部分的库。因此,例如,如果您编写一个网络应用程序,它可能会使用windows内置的UPNP库,OSX上的Bonjour库,以及其他unix版本上的一些其他零配置服务。

    另一个例子是一个简单的记事本应用程序。它可能会对正在运行的操作系统使用本机保存文件对话框。每个操作系统都需要编译不同的版本,才能绑定到该操作系统的保存文件对话框库。

        6
  •  2
  •   John Bode    15 年前

    原语类型是可移植的,因为它们保证支持最小范围的值(例如,int类型必须 至少 支持范围为-32767到32767)的值。因为不同的体系结构有不同的需求,所以不能保证它们具有相同的大小或对齐限制。

        7
  •  1
  •   Gerhard    15 年前

    对于java/ruby/。。。有人移植了虚拟机,你的代码刚刚运行。只要您同意VM提供的服务,这就很容易了。 在C语言中,您必须自己完成所有工作,因为您可以直接与硬件和操作系统交互。这增加了依赖性,但给了您强大的功能和灵活性。这正是C语言伟大的原因,但如果你切换操作系统或硬件,这可能是一件痛苦的事情。

        8
  •  1
  •   anon anon    15 年前

    • C或C++编译器(虽然不是所有的标准库)
    • 任何汇编语言的汇编程序
    • 脚本语言的解释器
    • 文本处理工具,如sed、grep等。
    • 一个简单的编辑器(有人记得ed吗?)

    事实上,所有的基本开发工具都可以用C语言开发(而且历史上都是用C语言开发的),而无需使用操作系统特有的功能。

        9
  •  0
  •   duffymo    15 年前

    我认为这是因为每一个编译器一方面是标准的、可移植的,另一方面是使用最佳的、操作系统专有的特性。

        10
  •  0
  •   Sachin    15 年前

    与其他高级语言相比,C确实提供了更多的功能。

    不同的处理器(基于CISC和RISC),32位和64位将数据的位流按不同的顺序排列。有一些支持API来进行转换,但并非对所有情况都完全可靠。

    Windows和Unix具有自定义标志,这些标志需要用于构建。