我想知道,为什么在没有包含胶水代码的情况下让程序在许多操作系统(如Windows和Linux)中运行太难了。它们都共享相同的架构(x86),所以我认为它应该很简单。此外,C是标准化的,那么为什么这些操作系统的实现不同?为什么难以遵循标准并为所有操作系统实现通用库?
我已经在C中编程了近两年,目前我使用glib来实现可移植性。
我不是在寻找这个问题的解决方案,我已经为此目的使用了glib。但是我想知道为什么它是必要的,为什么制作一个没有差异的C库是很困难的。
[ADD]
例如,当我用C / Glib编写程序时,我使用gchar / gint等类型确实是C基元类型,在wikipedia中关于glib,它说:
“功能
在基本层面上,GLib提供了类型定义,取代了c原型char,int,float等,以提高可移植性“
为什么C基元类型不可移植且是整个语言?
感谢所有答案。
答案 0 :(得分:26)
使您的基本C程序计算一点并打印结果很容易。
问题在于任何实质性的C程序都将依赖于操作系统中的大量服务,并且这些服务在很多方面存在差异。文件I / O往往类似,但在图形方面,它们差别很大。这就是问题的症结所在。
答案 1 :(得分:19)
为什么C基元类型不可移植且是整个语言?
在创建C时,最重要的是int
使用目标机器的自然字大小(或半字大小)(当时在PDP上可能是18或36位) -10!),并且int
中的位数可以很容易地预测,并且不太重要,更不用说在所有硬件上都相同。效率是最重要的考虑因素,一个程序没有太多的指令尤其重要,因此它可以被包装到当天的小记忆中。例如,没有人会想要在16位机器上模拟32位算术 - 这可能使算术运算所需的指令数量增加三倍,从而无法将更大的程序放入内存中。
为什么实施通用库很难?
这一点都不难。问题不在于没有通用的图书馆;问题是人们无法就什么构成通用图书馆达成一致。 (参见:GTK,KDE,QT,AT& T U / WIN + AST,等等令人作呕。)但实现好的库确实很难。至于为什么这很难:图书馆设计只是一个难题,合理的人可以而且对于什么是好的设计不一致。因此,多个设计激增,可移植性由董事会完成。
C带来的非常薄的标准库加剧了这种情况。但是我们不要忘记,程序员很幸运能够获得64KB的代码和64KB的数据库。到C ++出现的时候,他们可以像标准模板库那样标准化一个巨大的臃肿的猪。但是当设计C库时,的内容很小。现在,当标准C库不适合当今更加雄心勃勃的应用程序时,所有C程序员就单一标准达成一致为时已晚。
戳一位教授,开个讲座......
答案 2 :(得分:15)
如果您坚持核心标准并不难(K& R中的示例通常会以最小的校正运行)。但核心标准并不支持人们想要做的许多事情。像小事这样的小事:
关于基元类型的可移植性:标准指定了这些类型的最小大小限制,但未指定实际大小。大多数平台都支持大于最小值的大小,但并非所有平台都具有相同更大的大小。所以glib和其他跨平台项目定义了他们自己的类型,因此他们只需要一个的#ifdef
个开关来获得正确的大小。
答案 3 :(得分:7)
您的C程序与之交互的任何内容都将成为依赖项。如果这些依赖项在所有系统上的每个C实现中都是完全相同,那么你很幸运,你的程序是可移植的。
基本文件I / O操作就是这样。
但是,如果在系统上实现代码的方式存在一个差异,那么它就不再可以移植到该系统。
因此,如果您的代码没有触及任何内容,那么它就是可移植的。
我认为这里的主要想法是最大化可移植性,这样您就可以最大限度地减少必须更改以移植到新系统的内容。
答案 4 :(得分:3)
代码是可移植的,但这不是问题。
问题是大多数大型应用程序使用属于操作系统的库。因此,例如,如果你编写一个网络应用程序,它可能会使用Windows内置的UPNP库,OS X上的Bonjour库,以及其他unix版本的其他零配置服务。
另一个例子是一个简单的记事本应用程序。它可能会使用运行它的操作系统的本机保存文件对话框。需要为每个OS编译不同的版本以绑定到该OS的保存文件对话库。
我希望这些例子足够清楚:)
答案 5 :(得分:1)
对于java / ruby / ...有人移植了VM,你的代码就运行了。只要您对VM提供的服务没问题,这就很容易。 在C中,您必须为自己完成所有工作,因为您可以直接与硬件和操作系统进行交互。这增加了依赖性,但为您提供了强大的功能和灵活性。这就是使C很棒的原因,但是如果你切换操作系统或硬件,这可能会很痛苦。
答案 6 :(得分:1)
显然,某些软件需要特定于操作系统的功能,但考虑在C中创建的内容而不使用这些内容非常有趣:
事实上,所有基本开发工具都可以在C中开发(并且历史上是开发的),而不使用特定于操作系统的功能。
答案 7 :(得分:1)
为什么C基元类型不可移植且是整个语言?
基本类型是可移植的,因为它们保证支持最小范围的值(例如,int类型必须至少支持值在-32767到32767范围内)。它们不能保证具有相同的大小或对齐限制,因为不同的体系结构具有不同的要求。
C标准试图在可移植性,性能和易于实现之间取得合理的平衡,这意味着在所有这三个方面都存在妥协。编写有用且简单易用的C程序是可能的,但这意味着将自己局限于命令行驱动的接口,简单的文件I / O,并且不对字大小或对齐做出任何假设。
请记住,C是70年代早期的产品,当时占主导地位的计算环境包括通过基于字符的哑终端访问的大型时间共享系统;处理器时间和内存都很昂贵,而且数据中心很少一次支持一个或两个以上不同的平台,因此性能比逐字节可移植性更受关注。四十年后,情况不再如此,但也有四十年的遗留代码需要支持,因此语言定义不能过于彻底地改变。
答案 8 :(得分:0)
我认为这是因为每一台编译器在标准和便携之间以及在另一方面使用最佳的操作系统专有功能之间存在紧张关系。
我认为ANSI C代码非常便携,只要您写入标准。您的代码可移植到GNU和Microsoft都遵守标准的程度。
答案 9 :(得分:0)
不同的处理器(基于CISC和RISC),32位和64位确实以不同的顺序放置数据的比特流。有一些支持API可以进行转换,但对于所有情况都不完全可靠。
Windows和Unix都有自定义标志,需要用于构建。