使用C+;编译C代码时会遇到哪些问题+;编译程序? 如果你使用一个现存的C代码库并用C++编译器编译,你会发现什么样的问题?例如,我认为将一个整数赋给枚举类型的值将在C++中失败,而C.中的合法(如果有点讨厌)。

使用C+;编译C代码时会遇到哪些问题+;编译程序? 如果你使用一个现存的C代码库并用C++编译器编译,你会发现什么样的问题?例如,我认为将一个整数赋给枚举类型的值将在C++中失败,而C.中的合法(如果有点讨厌)。,c++,c,compiler-construction,migration,language-interoperability,C++,C,Compiler Construction,Migration,Language Interoperability,如果我不将所有的C文件包装在externC{…}中,我会在我最不希望的地方弄乱名称吗?我真的不应该这么做,有什么原因吗 背景,我们有一个很大的C++代码基础。几年来,我们一直在跳转,通过C++来实现自然的事情(例如,HOBBRWE继承)。我们想开始走向C++,但是逐渐地;获取我们的CORBA框架来支持它,并且重构模块,我们将利用更自然的方法来提供C++。查看所有不兼容的非常详细的列表。有很多微妙的问题,包括一些不会立即在编译器错误中表现出来的问题。例如,一个可能成为问题的问题是字符常量的大小:

如果我不将所有的C文件包装在
externC{…}
中,我会在我最不希望的地方弄乱名称吗?我真的不应该这么做,有什么原因吗

背景,我们有一个很大的C++代码基础。几年来,我们一直在跳转,通过C++来实现自然的事情(例如,HOBBRWE继承)。我们想开始走向C++,但是逐渐地;获取我们的CORBA框架来支持它,并且重构模块,我们将利用更自然的方法来提供C++。

查看所有不兼容的非常详细的列表。有很多微妙的问题,包括一些不会立即在编译器错误中表现出来的问题。例如,一个可能成为问题的问题是字符常量的大小:

// In C, prints 4.  In C++, prints 1
printf("%d\n", sizeof('A'));

我曾经做过这样的事。问题的主要来源是C++对类型的要求更严格,正如你所怀疑的。如果void*与其他类型的指针混合,则必须添加强制转换。如分配内存:

Foo *foo;
foo = malloc(sizeof(*foo));
上面是典型的C代码,但需要在C++中转换:

Foo *foo;
foo = (Foo*)malloc(sizeof(*foo));

< C++ >中有新的保留词,如“类”、“和”、“BOL”、“catch”、“删除”、“显式”、“可变”、“命名空间”、“新”、“操作符”、“或”、“私有”、“保护”、“朋友”等。这些变量不能用作变量名,例如

。 <>上述可能是用C++编译器编译旧C代码时最常见的问题。有关不兼容的完整列表,请参阅


你也会问关于名字的问题。在没有外部“C”包装的情况下,C++编译器会使符号变为碎片。只要使用C++编译器,不依赖于DLScript(或),从库中提取符号,这就不是问题。P> > P>另一个例子:C++中没有从int到隐式的隐式转换,而在C.中有一个如果需要在C++中进行转换,则需要一个强制转换。

C++具有更严格的类型检查,因此您可能需要向MalC/CyLoC/CaloC中的每个调用添加一个强制转换。

< P>如果我不将所有的C文件都打包到“ExtCult{}”中,我会在我最意想不到的地方弄脏我的名字吗

当你试图把C和C++连接到一起时,它会咬你。 我已经编写了很多头文件,其中包含:

#ifdef __cplusplus
    extern "C" {
#endif

// rest of file

#ifdef __cplusplus
    }
#endif
一段时间后,它合并到现有的multipleinclude样板文件中,您就看不到它了。但你必须小心你把它放在哪里-通常它属于任何包含你的标题之后

我真的不应该这么做,有什么原因吗

<>如果你确信你不会把C和C++结合起来,那么我就没有理由去做我知道的事情了。但是,随着您描述的渐进迁移,对于具有C接口和C++组件都需要使用的已发布接口的任何东西来说都是必不可少的。
不这样做的主要原因是它可以防止重载函数(至少在那些头中)。你可能会发现,一旦你将所有代码迁移到C++,并开始维护/重构/扩展它,你就想这样做。

< P>我在使用MSVC之前已经做过了,如果使用MSVC,一个好的策略是:

  • 将单个文件设置为构建为CPP,这样您就可以增量地移动到CPP编译器
  • 使用ctrl+f7一个文件一个文件地工作,只需构建一个文件
  • 您可以创建一个模板版本,而不是强制转换所有malloc
  • foo=(foo*)malloc(sizeof(*foo))

    变成

    foo = malloc<Foo>();
    
    foo=malloc();
    
    当然,对于需要Foo+n字节的情况,可以使用重载


    我还建议在可能的情况下,切换内存分配以使用RAII,我发现有些函数非常复杂,因此切换到RAII的风险太高,在大多数情况下,这非常简单。

    一般来说,您不会遇到任何问题。是的,C和C++之间有一些不兼容,但它们似乎并没有出现,除了上面提到的Maloc铸件,这是很难修复的。 我已经成功地编译并使用了以下开源C库作为C++:

    • Expat XML解析器
    • FreeType2字体光栅化器
    • libjpeg:处理JPEG图像
    • libpng:处理PNG图像
    • Zlib压缩库

    最难的部分是添加命名空间包装器,这花费了几个小时,主要是因为包含在代码中深藏的代码包含在C++命名空间之外。 我为什么要这样做?因为我卖的是一个商业图书馆,人们直接链接到他们的应用程序中;有时他们的应用程序会链接到其他版本的Expat、FreeType等。这会导致多重定义的符号错误。最干净的做法是将库中的所有内容移动到我的命名空间中


    然而,我并没有在我使用的所有开源库中这样做。有些还没有引起冲突,我还没来得及解决它们,尽管没有麻烦是相当乏味的。有趣的例外是SQLite,我不能在C++中编译。所以我做了大量的搜索和替换,在每个外部可见的符号上添加了前缀(我的产品名称)。这解决了我的客户的问题。

    < P>尝试用C++编译器编译:

    typedef enum{ false = 0, true = 1} bool;
    

    有些C++保留词在某些情况下也是关键字,包括“包含”、“包含”等。“C++中有新的保留词”。我摔倒的是“这个”。当你有模糊的O-C代码时,有人很可能用它来表示,好吧,C++中的意思…ououh!我已经放弃了