当前位置:  开发笔记 > 编程语言 > 正文

Windows上的C编译器之间有什么实际区别?

如何解决《Windows上的C编译器之间有什么实际区别?》经验,为你挑选了4个好方法。

用Visual C/C++ 2005/2008编写的程序可能无法使用其他编译器(如GNU C/C++)编译,反之亦然.例如,当尝试重用使用windows.h的代码时,为另一个特定的编译器编写代码时,需要注意哪些差异?

是否有任何关于如何生成与一个编译器或另一个编译器兼容的代码的信息,例如GC/C++或MSVC/C++?这会导致什么问题?

那么其他编译器呢,比如LCC和Digital Mars?



1> JesperE..:

尝试将为MSVC编写的代码编译到其他编译器时,首先要做的是在关闭Microsoft扩展的情况下编译它.(我认为使用/ Za标志).这将吸引大量GCC和其他编译器会抱怨的事情.

下一步是确保Windows特定的API(MFC,Win32等)在Windows特定的文件中被隔离,从而有效地将您的代码分成"通用"和"特定于Windows"的模块.



2> Steve Jessop..:

请记住,如果您希望您的网页在不同的浏览器上运行,那么您应该编写符合标准的HTML吗?

编译器也是如此.

在语言层面,如果您的代码在GCC上编译而没有警告,使用-std = c89(或-std = c ++ 98 for C++),-pedantic -Wall,加上-Wextra,如果你感觉很勇敢,并且只要你还没有使用-pedantic允许的任何更明显的GNU扩展(这很难意外),那么它很有可能在大多数C89编译器上工作.C++有点不太确定,因为您可能依赖于目标编译器对标准的支持程度.

编写正确的C89有点限制(没有//注释,声明必须在块中的语句之前,没有内联关键字,没有stdint.h,因此没有64位类型等),但是一旦习惯它就不会太糟糕.如果你关心的只是GCC和MSVC,你可以打开一些你知道MSVC的语言功能.否则,您可以编写自己的"语言抽象"标题.例如,在GCC和MSVC/C++上将"内联"定义为"内联",但在MSVC/C中定义为"__inline".或者MSVC stdint.h很容易找到或写入.

我以前成功编写了可移植代码 - 我主要使用GCC在一个特定产品的平台上工作.我还编写了可在所有平台上使用的代码,包括Windows XP和Mobile.在构建服务器上运行"测试构建"之前,我从未为这些平台编译过它,而且我很少遇到任何问题.我想我可能编写了错误的代码,触发了一次或两次64位兼容性警告.

另一方面,Windows程序员引起了偶尔的问题,主要是因为他们的编译器不像我们那样迂腐,所以我们看到他们没有警告,而不是GCC根本不支持的事情.但修复警告意味着当代码稍后在具有更原始编译器的系统上使用时,它仍然有用.

在图书馆一级,这要困难得多.如果#include并通过windows.h使用Windows API,那么显然它不适用于linux,如果你使用KDE和GCC然后尝试使用MSVC进行编译也是如此.

严格来说,这是一个平台问题,而不是编译器问题,但它是相同的事情.如果你想编写可移植代码,你需要一个OS抽象API,比如所有目标支持的POSIX(或其子集),并且当你首先编写它时,你需要考虑"可移植".使用大量使用特定于Windows的API的代码,并尝试使其在GCC/linux上运行,基本上是一个完整的重写AFIAK.使用WINE可能比尝试重新编译它更好.



3> 小智..:

你正在混淆"编译器"和"操作系统".不是MSVC C编译器带给表的东西:它是Windows API的C特定实施例.您可以从Visual Studio中独立获取它.Windows上的任何其他C编译器都可能提供它.例如,在Linux方面,您有,等.它们不是GCC的重要组成部分,任何其他编译Linux的编译器都会提供它们.

所以你需要回答两个不同的问题:如何以任何编译器接受它的方式编写C?如何隐藏我对操作系统的依赖?



4> MattyT..:

从各种答案可以看出,这个主题非常复杂.记住这里我最近将一些代码移植到三个平台(msvc 8/Windows,gcc 4.2/Linux,gcc 3.4 /嵌入式ARM9处理器)时遇到的一些问题.它最初只在Visual Studio 2005下编译.

a)在Windows平台上编写的许多代码都使用在windows.h中定义的类型.我必须创建一个"windows_types.h"文件,其中包含以下内容:

#ifndef _WIN32
    typedef short              INT16;
    typedef unsigned short     UINT16;
    typedef int                INT32;
    typedef unsigned int       UINT32;
    typedef unsigned char      UCHAR;
    typedef unsigned long long UINT64;
    typedef long long          INT64;
    typedef unsigned char      BYTE;
    typedef unsigned short     WORD;
    typedef unsigned long      DWORD;
    typedef void *             HANDLE;
    typedef long               LONG;
#endif

丑陋,但比修改以前只针对Windows的代码要容易得多.

b)模板化代码中不需要typename关键字来声明类型.MSVC在这方面是松懈的(虽然我假设某些编译器开关会产生警告).不得不在很多地方添加它.

c)简单但耗时:Windows不区分大小写,并且许多#included文件在Linux下指定了不正确的情况导致问题.

d)有很多代码使用Windows API来处理很多事情.一个例子是CRITICAL_SECTIONS和INTERLOCKED_INCREMENT.我们尽可能地使用boost库来替换这些问题,但重新编写代码非常耗时.

e)许多代码依赖于头文件包含在预编译头文件中.我们在gcc3.4上使用pch时遇到了问题,因此我们必须确保所有.h/cpp文件都正确地包含了所有依赖项(因为它们应该首先包含在内).

f)VS 2005有两个令人讨厌的错误. auto_ptr可以分配给任何东西,允许临时变量传递给引用参数.两者都无法编译(谢天谢地!)在gcc下,但需要返工.

g)奇怪的是,我们有模板代码试图明确地专门化模板函数.不允许.再次gcc拒绝,VS 2005让它走了.一旦理解了问题,就足够容易重新定期进行超载.

h)在VS 2005下,允许使用字符串构造std :: exception.不允许使用gcc或标准.重新编写代码以优先使用其中一个派生的异常类.

希望这是您正在寻找的那种信息!

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有