最近在写代码过程中,发现一个问题,编译总是过不去,报错如下:

stdint.h::: error: duplicate 'unsigned'
stdint.h::: error: 'long long long' is too long for GCC

打开stdint.h这个文件,发现120行是这样的内容:

#if __have_long64
typedef signed long int64_t;
typedef unsigned long uint64_t;
#define __int64_t_defined 1
#elif __have_longlong64
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#define __int64_t_defined 1
#elif __STDINT_EXP(INT_MAX) > 0x7fffffff
typedef signed int int64_t;
typedef unsigned int uint64_t;
#define __int64_t_defined 1
#endif

继续查找,发现我们代码中的某一个头文件中有这样的定义:

#ifndef uint64_t
#define uint64_t unsigned long long
#endif

在这个头文件中,把上面这三行注释掉之后,在include<stdint.h>,编译通过。

按这个头文件名为a.h来说,在一个C文件中,我对a.h和stdint.h的关联顺序为:

#include "a.h"
#include <stdint.h>

main函数就是一个简单的helloworld打印。

生成预处理后的文件:

gcc -E test.c -o test.i

在test.i中,发现了这样的typedef定义:

typedef unsigned long int unsigned long long;

我再把C文件中include "a.h"注释掉,test.i的对应行是这样的:

typedef unsigned long int uint64_t;

所以,发现在编译过程中,#define定义的被替换掉了,在编译时,就会报错。

但是为什么报错unsigned 和 long long long两个error,还需要进一步探索。。。我个人猜测是因为编译器的底层的原因。

总结

define在预处理阶段,typedef在编译阶段,两个头文件中都定义了uint64_t,定义方式不同,导致编译过程中,编译器认为我们声明一个long long long的数据类型。

typedef和define混用产生的错误的更多相关文章

  1. typedef 和 #define 的区别

    本文已迁移至: http://www.danfengcao.info/c/c++/2014/02/25/difference-between-define-and-typedef.html typed ...

  2. typedef和#define的用法与区别

    typedef和#define的用法与区别 typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程 ...

  3. typedef 与define 的区别

    typedef和#define的用法与区别   typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译 ...

  4. typedef 优于 #define

    案例一: 通常讲,typedef要比#define要好,特别是在有指针的场合.请看例子: typedef char *pStr1; #define pStr2 char *; pStr1 s1, s2 ...

  5. typedef和#define的区别

    转自:http://www.cnblogs.com/kerwinshaw/archive/2009/02/02/1382428.html 一.typedef的用法在C/C++语言中,typedef常用 ...

  6. typedef与define

    一.typedef用法 typedef常用来定义一个标识符及关键字的别名,它生效是在语言编译过程,但它并不实际分配内存空间.typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性” ...

  7. typedef和define具体的具体差别

      1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,仅仅有在编译已被展开的源程序时才会发现可能的错误并报错.比如: #define PI 3. ...

  8. typedef和define具体的具体差异

      1) #define这是一个预处理指令,简单的更换当预处理程序.不检查的正确性,仍不能正常关机进入的意思,那里只是已被展开时编译源代码会发现可能的错误和错误. 例如: #define PI 3.1 ...

  9. typedef和define具体的详细区别

    1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错.例如: #define PI 3.141 ...

随机推荐

  1. redis_3 持久化

    快照持久化在本地硬盘保存的数据备份文件: 三个save的意思:数据修改的频率越高,保存的频率也越高,反之. 由于快照持久化是把所有的key和值都备份一遍,这样的操作很消耗资源,为了让系统资源过度的浪费 ...

  2. Loaded APR based Apache Tomcat Native library 1.1.24 using APR version 1.4.6.

    Loaded APR based Apache Tomcat Native library 1.1.24 using APR version 1.4.6. 我复制的几个地方: MySql C:\WIN ...

  3. Global UNIX file system cylinder group cache

    A global cylinder group (CG) cache is stored in file server memory and shared by a plurality of file ...

  4. SQL-Oracle-创建Dblink

    create database link DBLINK_IMARK_RAC connect to imark identified by imarkDB12345 using '(DESCRIPTIO ...

  5. Python模块路径查找

    本文主要介绍如何查找某个Python模块的绝对路径,下面以opencv模块的查找为例.有两种方法 第一种方法 打开一个终端,输入 python -v import cv2 最后一行显示如下 第二种方法 ...

  6. leetcode_Isomorphic Strings _easy

    Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...

  7. 又一次发现Oracle太美之glogin.sql

    又一次发现Oracle太美之glogin.sql 刚開始接触Oracle的时候,有时候一登陆一个生产环境.常常会出现以下的情况: [oracle@rh64 app]$ sqlplus / as sys ...

  8. ”危险“的RESTRICT与GCC的编译优化(编程者对编译器所做的一个“承诺”:使用restrict修饰过的指针,它所指向的内容只能经由该指针修改)

    restrict是C99标准中新添加的关键字,对于从C89标准开始起步学习C语言的同学来说(包括我),第一次看到restrict还是相当陌生的.Wikipedia给出的解释如下: In the C p ...

  9. MyEclipse2015安装SVN插件

    一.下载SVN插件subclipse 下载地址:http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240 在打开的网 ...

  10. BZOJ 4358 坑 莫队+线段树 死T

    这是一个坑 竟然卡nsqrt(n)logn T死 等更 //By SiriusRen #include <cmath> #include <cstdio> #include & ...