C语言聊言C语言中常常表现数据类型在32跟64位机上的使(zz)

一言九鼎字: c语言,数据类型,32各类,64各类

1、概述

  C语言有一对可怜基本的数据类型,正是这些基本型为咱们可以延长了不过的用户从定义类型,本文主要介绍了
int, size_t, time_t, long, long long int 等核心数据类在Linux32 及
Linux64
的使状态。表面看上去,这些类别确实尽基础极简单,似乎从未啥可道的,实事似乎也是这样,用过C的针对性这些都曾经不行熟悉了,这还为此讲话?在PC 64员机器
出来前,我们真正并非太关注这些,因为在32号机上编程,似乎大少出现了什么问题,但64位机出来了,象Linux
也支撑64各机器,问题即使来了,为什么?因为它的长有了转移,而我辈的顺序为不怕发或用转移一下。

2、举例

优先选出个例,如下:

 

C代码

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3.  
  4. staticvoid get_length(size_t *size) 
  5.     if (size) 
  6.         *size = 100; 
  7.  
  8. staticvoid test(void) 
  9.     char *buf = strdup(“hello world”); 
  10.     int  n; 
  11.  
  12.     printf(“buf: %s\n”, buf); 
  13.     get_length((size_t*) &n); 
  14.  
  15.     printf(“buf: %s, n: %d\n”,  buf, n); 
  16.     free(buf); 
  17.  
  18. int main(int argc, char *argv[]) 
  19.     test(); 
  20.     return (0); 
  21. #include #include static void get_length(size_t size) { if (size) size = 100; } static void test(void) { char buf = strdup(“hello world”); int n; printf(“buf: %s\n”, buf); get_length((size_t) &n); printf(“buf: %s, n: %d\n”, buf, n); free(buf); } int main(int argc, char *argv[]) { test(); return (0); }

 

  首先用这程序在32位机的 Linux 上运行一下,如下:

buf: hello world

buf: hello world, n: 100

OK,如我辈所预期,一切正常。

 

  然后重新将头程序于64位机的 Linux 上运行一下,如下:

buf: hello world

buf: (null), n: 100

  奇怪的景象出来了,怎么printf出的结果吧空呢?晕菜,为啥经过
get_length()/1 后世界改变了,buf 的情节尚未了,被针对一个空指针,而 buf
明明是还不曾受放飞呀。赶快用 valgrind 检查一下,

valgrind –tool=memcheck –leak-check=yes –show-reachable=yes ./a.out

“2 bytes in 1 blocks are definitely lost in loss record 1 of
1”,说发块内存未被放出,而在 test() 后面确释放了 buf
呀,谁悄悄地给自由了一旦并未报我?更晕菜,难道是 libc 的题材?再用
valgrind
在32位机检查一下,一切OK,没有起64员机上的荒唐提示,说明内存确实是因为
test() 中之 free(buf) 释放了。

  正当对是题材百思不解时,忽然想到一个问题 int * 至 size_t* 
类型转换会不见面产生问题?因为 size_t
在32位机上是4字节,而当64号机上是8字节,int在32各类以及64各类机上都是4字节,嗯,问题虽在于这,再回头仔细瞧上述代码,在
test() 中将 &n 由 int * 强制转换成 size_t *,
这样好避编译警告,但于 get_length()/1 中为?它是免会见知道 size_t
*size 中 size 所指空间是4字节的,而依然当8字节对照,这样于对 *size =
100 进行赋值时就是产生了改变,size
所倚的8字节空间发出变更,而实际上应单独改变4字节才是,这便是问题之关键所在,所以当遇到此类题材常常,一定得只要留意基本项目在不同机器及的空间尺寸了。

 

3、小结

  以上之例子只是一个简约的例证,也许还易看得出来,当我们的项目比坏时,这种不当或会见偶尔发生瞬间,那可能就是沉重之了,因为偶然其并无
会招程序
异常退出来core文件,但也会改我们的运转结果,本人就用问题调试了点儿龙多的岁月才找到原因,另外,即使用问题发生了
core 文件,你见面发现用 gdb 调试该 core 时向找不交因所在。

 

下列有一部分着力项目在32号以及64各类机上的大小区别

  int long size_t time_t long long int
32位机器 4字节 4字节 4字节 4字节 8字节
64位机器 4字节 8字节 8字节 8字节 8字节

 

每当形容过平台的次第时,一定要留心这些骨干项目的长短大小。


一如既往、程序运行平台
       不同的阳台达成对两样数据类型分配的字节数是见仁见智之。
       个人对平台的接头是CPU+OS+Compiler,是坐:
       1、64位机器也得以伪装32号系统(x64装XP);
      
2、32员机器上可发16/32位的编译器(XP上发生tc是16各类的,其他大的是32各之);
       3、即使是32号之编译器也堪将来64各项之integer来(int64)。
      
以上这些是因广泛的wintel平台,加上我们也许怪少会接触的其它平台(其它的CPU和OS),所以个人认为所谓平台的概念是三者的结。
      
虽然三者的尺寸可以无一致,但显然相互配合(即长度等,32各类之CPU+32各项的OS+32各之Compiler)发挥的能量最充分。
       理论上来讲
我觉着数据类型的字节数应该是由CPU决定的,但是事实上主要由于编译器决定(占小位由编译器在编译期间决定)。

其次、常用数据类型对承诺字节数
       可用如sizeof(char),sizeof(char*)等得出

       32员编译器:

       char :1个字节
       char*(即指针变量): 4个字节(32各的寻址空间是2^32,
即32独bit,也尽管是4个字节。同理64号编译器)
       short int : 2个字节
       int: 4个字节
       unsigned int : 4个字节
       float: 4个字节
       double: 8个字节
       long: 4个字节
       long long: 8个字节
       unsigned long: 4个字节

       64各类编译器:

       char :1个字节
       char*(即指针变量): 8单字节
       short int : 2个字节
       int: 4个字节
       unsigned int : 4个字节
       float: 4个字节
       double: 8个字节
       long: 8个字节
       long long: 8个字节
       unsigned long: 8个字节