`
de3light
  • 浏览: 13831 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

X86_64平台下strtoul诡异问题,都是#include惹的祸?

阅读更多
环境CentOS 5.4 X86_64 gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
碰到一个strtoul的诡异问题,简化出来就是这个程序
#include <stdio.h>

int main(){
  char *a = "4297757104";
  unsigned long int l = strtoul(a, NULL, 0);
  printf("%lu\n", l);
  return 0;
}

结果输出2789808而非4297757104。查了半天手册也没发现什么不对的,发现手册中有#include <stdlib.h> ,加上去居然就对了。百思不解,原来编译也能通过,为什么加个头文件就导致程序行为改变了?

之前也听说过GCC对某些函数会做内部特殊处理。既然程序行为改变,二进制级别上肯定就有区别。先用objdump -T long 将动态链接的函数导出一看,都一样。干脆直接objdum -S long> long.s 把程序反汇编,然后diff查看,结果发现没有加include的版本,多了cltq 这么条指令
  40050b:       e8 e8 fe ff ff          callq  4003f8 <strtoul@plt>
  400510:       48 98                   cltq
就是罪魁祸首了。这条指令是将eax寄存器的值符号扩展到rax。
4297757104的二进制是100000000001010101001000110110000,其中低32位截取下来是00000000001010101001000110110000,然后符号扩展到64位,只要将高32位补0即可。换算下来,刚好就是2789808。也就是说,这条指令把rax高32位的数据给清掉了。

教训:还是那两句老话
1)编译时一定要加上 -Wall,加上之后就会报一个 warning: implicit declaration of function 'strtoul'。否则,怎么死的都不知道。
2)不要忽略任何warning
不过,这个warning对于我等新手来说,很容易无视,也很难明白其中含义
分享到:
评论

相关推荐

    led_driver

    头文件 #include 定义函数 unsigned long int strtoul(const char *nptr,char **endptr,int base); 函数说明 strtoul()会将参数nptr字符串根据参数base来转换成无符号的长整型数。参数base范围从2至36,或0。参数...

    浅析C语言中strtol()函数与strtoul()函数的用法

    主要介绍了浅析C语言中strtol()函数与strtoul()函数的用法,注意其将字符串转换成long型的区别,需要的朋友可以参考下

    uboott移植实验手册及技术文档

    在文件的最后加入Nand Flash的初始化函数,该函数在后面Nand Flash的操作都要用到。 u-boot运行到第2阶段会进入start_armboot()函数。其中nand_init()函数是对nand flash的最 初初始化函数。nand_init()函数在两个...

    atoi,atol,strtod,strtol,strtoul实现类型转换.doc

    atoi,atol,strtod,strtol,strtoul实现类型转换.doc

    strtoul函数的使用(将字符串转换成无符号长整型数)

    之前使用strtoul函数时,从来没思考过它的用法,最近在编写驱动设计时,突遇这个函数,发现这函数还是有值得探讨的地方。

    68k反汇编源代码

    char dis_op[64], dis_inst[32], dis_arg[24]; UINT32 start_addr = 0, org = 0, do_org = 0, len = 0, fsize, i, j, k, file_i = 0; FILE *fp; UINT8 *buffer; char *c; /* * Process the command line *...

    vc6 std 调用 十六進制 轉化

    vc6 std c++ call

    MFC 数值转换 CString >> HEX>>DEC>> CString

    在MFC通信模块中经常会遇到数据类型的转换,比如会收到下位机的数据(如:10 20 30 40 64 DD ),需要在Dailog中显示'0x64'为'100 Dec',那必须先从CString &gt;&gt; HEX&gt;&gt;DEC&gt;&gt; CString 实行代码如下: CString readData...

    c/c++函数库说明(api)html版

    #include (preproc) insert (cppdeque) insert (cpplist) insert (cppmap) insert (cppmultimap) insert (cppmultiset) insert (cppset) insert (cppstring) insert (cppvector) isalnum (stdstring) ...

    C标准库函数.CHM

    1.7.3 #include 1.7.4 #line 1.7.5 #error 1.7.6 #pragma 1.7.7 Predefined Macros 2. Library 2.1 assert.h 2.1.1 assert 2.2 ctype.h 2.2.1 is... Functions 2.2.2 to... Functions 2.3 errno.h ...

    c语言标准库中字符转换函数和数字转换函数

    #include atoi();将字符转换为整型 例:char ch1;int i=atoi(ch1); atol();将字符转化为长整型 例:char ch2;long l=atol(ch2); atof();将字符转化为浮点型 例:char ch3;float f=atof(ch3); strtod(); 将字符串...

    Keil C51 库函数源码

    声 明: 逆向以学习和研究为目的,版权属于Keil公司. ...strtoul atan2 ceil cosh floor fmod modf pow sinh tanh gets strcat strcspn strncat strncmp strncpy strpbrk strrchr strrpbrk strrpos strspn strstr

    -C++参考大全(第四版) (2010 年度畅销榜

    10.4 #include 10.5 条件编译指令 10.6 #undef 10.7 使用defined 10.8 #line 10.9 #pragma 10.10 #和##预处理器运算符 10.11 预定义的宏名 10.12 注释 第二部分 C++的专有特征 第11章 C++语言概述 11.1 C++的起源 ...

    CoderJackyHuang#MDArtileFiles#iOS任意进制转换1

    前言今天在处理进制转换时,突然看到iOS里面的一个很神奇的函数:strtoul,这可以进行进制的转换。本篇文章的主题就是讲讲这个strtoul神奇的函数,如何帮

    c语言字符串_数字转换函数大全

    atof(将字符串转换成...strtoul(将字符串转换成无符号长整型数) toascii(将整型数转换成合法的ASCII 码字符) toupper(将小写字母转换成大写字母) tolower(将大写字母转换成小写字母) …… …… 各种转换函数详细介绍

    linux_c API函数大全

    strtoul(将字符串转换成无符号长整型数) 25 2.8 25 toascii(将整型数转换成合法的ASCII 码字符) 25 2.9 26 tolower(将大写字母转换成小写字母) 26 2.10 26 toupper(将小写字母转换成大写字母) 26 3.内存控制...

    eduOS:一种教学操作系统,可在系统软件的设计中获得更深入的知识

    umoddu3,udivdi3,qdivrem,divdi3,lshrdi3,moddi3,strtol,strtoul,ucmpdi2 该软件包含从美国电话电报公司或Unix系统实验室公司许可给加利福尼亚大学的材料中获得的代码,并在UNIX系统实验室公司的许可下在...

    C语言常用数字和字符串转换函数

    C语言常用数字和字符串转换函数,toi 字符串转换成整型数 atol 字符串转换成长整型数 atof 字符串转换成浮点型数 strtol 字符串转换成长整型数 strtoul 字符串转换成无符号长整型数 strtod 字符串转换成浮点数

    C库函数(字符串转换篇)

    包括的函数: atof 将字符串转换成浮点型数 ...strtoul 字符串转换成无符号长整型数 toascii 整型数转换成合法的ASCII 码字符 tolower:大写字母转换成小写字母 toupper:小写字母转换成大写字母

Global site tag (gtag.js) - Google Analytics