今天又发现了我的一个“不良习惯”,C语言的源文件用C还是CPP做后缀完全视心情而定,今天我就尝到苦头了,工程总是编不过去,准确的说是链接错误,后来发现工程下的文件多是c后缀的,只有一个是cpp后缀的,就把cpp后缀的改成了c后缀,编译、链接,OK了。
    在Google上搜索了一圈,发现就这一问题的文章比较少,也不是很系统,所以有了此篇小文,也是为了加深我的印象。
 
            结论:
            1.gcc认为.c的为C程序,.cpp的为C++程序;
            2.g++认为.c的为C++程序,.cpp的为C++程序;
            3.VC++的编译器cl认为.c的为C程序,.cpp的为C++程序;
            4.C程序与C++程序中同样的函数在编译后的obj文件中的symbol是不同的,所以以C方式编译的obj文件与以C++方式编译的obj文件无法成功链接。
 
            使个demo说明一下:
            准备工作:
            为gcc、g++、cl(VC++编译器)、link(VC++链接器)设置好环境变量
            //demo.cpp
            #include
            #include "foo.h"
            int main()
            { 
                printHello(); 
                return 0;
            }
 
            //foo.h
            void printHello();
 
            //foo.c
            #include
            void printHello()
            {
                printf("Hello MM");
            }
 
            1.gcc、g++测试,在windows的cmd下:
            D:\>g++ demo.cpp -o demo.obj -c (以C++方式编译生成demo.obj文件,-c选项表示只编译不链接)
            D:\>gcc foo.c -o foo.obj -c (以C方式编译生成foo.obj文件)
            D:\>g++ demo.obj foo.obj -o demo (链接demo.obj、foo.obj文件)
            demo.obj(.text+0x2b):demo.cpp: undefined reference to `printHello()'
            collect2: ld returned 1 exit status
                 提示说找不到printHello,因为按照C++的编译方式去找printHello应该对应某一种格式的symbol,但是我们
            的foo.obj中printHello的symbol是另外一种格式的,所以找不到了。
            把foo.c改成foo.cpp就可以成功链接了。
 
            2.cl、link测试,在windows的cmd下:
            D:\>cl demo.cpp /c (以C++方式编译生成demo.obj文件,/c选项表示只编译不链接)
            D:\>cl foo.c /c (以C方式编译生成foo.obj文件)
            D:\>link demo.obj foo.obj
            Microsoft (R) Incremental Linker Version 6.00.8168
            Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
            demo.obj : error LNK2001: unresolved external symbol "void __cdecl printHello(void)"(?printHello@@YAXXZ)
            demo.exe : fatal error LNK1120: 1 unresolved externals
            理由同上,把foo.c改成foo.cpp就可以成功链接了。
 
 
 
            参考文章:
            1.gcc和g++的区别(开源CEO)
               http://www.linuxdiyf.com/bbs/viewthread.php?tid=109684
            2.在 console mode 中使用 C/C++ 编译器(jjhou候俊杰)
               http://jjhou.csdn.net/article99-10.htm
 
            

【转】C与CPP后缀的文件在编译时的区别的更多相关文章

  1. codeblocks中cocos2dx项目添加新的.cpp和.h文件后编译运行的方法

    新建了cocos2dx项目后(比如我这里建立的项目名为Test01),项目目录下有如下目录和文件: bin CMakeLists.txt MyGame.layout proj.win10 Classe ...

  2. android学习-ndk-build(androidstudio编译cocos2d-x库的cpp为so文件的解释)

    本文不作为ndk初学使用,只是对cpp等c++文件编译成so文件的过程中,参数含义,及ndk配置的解释.使用的技术比较旧. androidStudio使用gradle调用ndk-build工具编译c+ ...

  3. 九、将cs文件快速的转换成可执行文件和响应文件(配置编译开关的文件)

    1.将包含多个类型的源代码文件转换为可以部署的文件.有如下Program.cs的文件,代码如下: public sealed class Program { public static void Ma ...

  4. 使用XSSFWork创建的xlsx后缀Excel文件无法打开

    使用XSSFWork创建的xlsx后缀Excel文件无法打开 标签: POIExcelmicrosoftxlsx 2015-04-21 10:49 1170人阅读 评论(2) 收藏 举报 分类: Ja ...

  5. python 之遍历目录树(可匹配输出特定后缀的文件)

    涉及到的模块有os, fnmatch:1.通过os模块中的方法获取dir.subdir.files,通过os.path.join可拼接成完整路径: 2.fnmatch主要通过fnmatch.fnmat ...

  6. 混合编译.c/.cpp与.cu文件

    混合编译.c/.cpp与.cu文件 项目中用到cuda编程,写了kernel函数,需要nvcc编译器来编译..c/.cpp的文件,假定用gcc编译. 如何混合编译它们,整体思路是:.cu文件编译出的东 ...

  7. Java 实现后缀xls文件读取

    Java 实现后缀xls文件读取 一.开发环境 poi采用的3.9版本 + JDK1.6 + Myeclipse 二,JAR包 三.实现代码 实体类:UserRoleBean package nc.x ...

  8. linux下查找指定后缀的文件

    1.linux下查找指定后缀的文件 例如查找当前目录下的所有后缀名时.c或.h的文件 find  .  -type f -regex  ".*\.\(c\|h\)"

  9. 解决Visual C++工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)的办法

    2014-01-17 23:36 5128人阅读 评论(1) 收藏 举报 分类: 资料集(282) 版权声明:本文为博主原创文章,未经博主允许不得转载. 之前使用网上的一个开源代码,被封装成Windo ...

随机推荐

  1. VMware-workstation-6.5.2-156735.exe

    480HD-KPZ2X-TA56C-4YTQQ VMware 12 专业版永久许可证密钥 5A02H-AU243-TZJ49-GTC7K-3C61N

  2. systemd服务内容详解

    systemd是Linux下的一种init软件,由Lennart Poettering带头开发,并在LGPL 2.1及其后续版本许可证下开源发布.其开发目标是提供更优秀的框架以表示系统服务间的依赖关系 ...

  3. C++的黑科技(深入探索C++对象模型)

    周二面了腾讯,之前只投了TST内推,貌似就是TST面试了 其中有一个问题,“如何产生一个不能被继承的类”,这道题我反反复复只想到,将父类的构造函数私有,让子类不能调用,最后归结出一个单例模式,但面试官 ...

  4. [实战]MVC5+EF6+MySql企业网盘实战(14)——逻辑重构

    写在前面 上篇文章关于修改文件夹和文件名称导致的找不到物理文件的问题,这篇文章将对其进行逻辑的修改. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6 ...

  5. openCV训练程序申请内存不足

     openCV训练程序申请内存不足   在用OpenCV训练分类器(特别是训练Adaboost类型的分类器)的时候,当样本的数量特别大的时候,就会出现申请内存不够的情况,很早以前碰到过这样的情况,最近 ...

  6. ubuntu 依赖问题

    ubuntu想装个QQ,无奈安装不但出错,还导致现在的软件依赖出了问题 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 您也许需要运行“apt --fix-b ...

  7. logstash收集java日志,多行合并成一行

    使用codec的multiline插件实现多行匹配,这是一个可以将多行进行合并的插件,而且可以使用what指定将匹配到的行与前面的行合并还是和后面的行合并. 1.java日志收集测试 input { ...

  8. c#多线程实现函数同步运行

    我们假设有方法run1()和run2(),耗时都比较大,实现他们同步运行将大大提高程序的效率,在这里考虑使用多线程的方法. 首先添加引用,定义bool型i,j为false. using System. ...

  9. SQL Join简单介绍

    前沿 Join是关系型数据库系统的重要操作之一,SQL Server中包含的常用Join:内联接.外联接和交叉联接等. 如果我们想在两个或以上的表获取其中从一个表中的行与另一个表中的行匹配的数据,这时 ...

  10. 首次使用ideal构建maven项目web

    如附件 链接:https://pan.baidu.com/s/1oH-9VfIKnLPjVt-tOH7fZw 提取码:7s5t