今天又发现了我的一个“不良习惯”,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. 常用的Oracle的doc命令

    常用的Oracle的doc命令 1.连接数据库 普通用户连接数据库: conn scott/tiger --(默认的用户名/密码).conn 即"connection"连接数据库的 ...

  2. awk中NF,NR的含义

    awk中NF和NR的意义,其实你已经知道NF和NR的意义了,NF代表的是一个文本文件中一行(一条记录)中的字段个数,NR代表的是这个文本文件的行数(记录数).在编程时特别是在数据处理时经常用到.建议你 ...

  3. Hadoop2.5.2 安装部署

    0x00 平台环境 OS: CentOS-6.5-x86_64 JDK: jdk-8u111-linux-x64 Hadoop: hadoop-2.5.2 0x01 操作系统基本设置 1.1 网络配置 ...

  4. 791. Custom Sort String

    S and T are strings composed of lowercase letters. In S, no letter occurs more than once. S was sort ...

  5. Ubuntu下Node.js开发起步之旅

    因为忙其它的事,把Node.js的学习放下了快两个月了,世事变化还真快,发现很多东东都改变了,express已经升级到4.x了,变化还不小! 我原来的学习过程是在VirtualBox中安装Ubuntu ...

  6. Codeforces Round #302 (Div. 1) D - Road Improvement 树形dp

    D - Road Improvemen 思路:0没有逆元!!!! 不能直接除,要求前缀积和后缀积!!! #include<bits/stdc++.h> #define LL long lo ...

  7. 【Java】 String和char[]类型间的相互转化

    (1)String类型转char[] 类型,使用String类型的toCharArray()方法: (2)char[] 类型转String类型,使用String.valueOf()方法: public ...

  8. SQL Join简单介绍

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

  9. 宝塔面板php扩展安装

    yum install libmcrypt libmcrypt-devel mcrypt mhash wget http://pecl.php.net/get/mcrypt-1.0.1.tgz tar ...

  10. 基于rsync方式的文件备份

    rsync 是一个快速增量文件传输工具,它可以用于在同一主机备份内部的备分,我们还可以把它作为不同主机网络备份工具之用.本文主要讲述的是如何自架rsync服 务器,以实现文件传输.备份和镜像.相对ta ...