环境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对于我等新手来说,很容易无视,也很难明白其中含义
分享到:
相关推荐
头文件 #include 定义函数 unsigned long int strtoul(const char *nptr,char **endptr,int base); 函数说明 strtoul()会将参数nptr字符串根据参数base来转换成无符号的长整型数。参数base范围从2至36,或0。参数...
- **相关函数**: `atoi`, `atol`, `strtod`, `strtol`, `strtoul` #### 功能说明 `atof`函数的功能是将传入的字符串转换为双精度浮点数。它会从字符串的起始位置开始,跳过前导空白字符,然后识别出一个可选的正负...
最后,在实际编程中,应当包含头文件 #include <stdlib.h> 来使用strtoul函数。测试代码可以用来验证函数的正确性,例如通过不同的输入值来检查转换是否成功,以及endptr是否指向了正确的结束位置。注意,使用时应当...
在C语言中,`strtol()` 和 `strtoul()` 是两个非常重要的字符串转换函数,用于将字符串转换为数值类型。这两个函数在处理长整型数(`long` 和 `unsigned long`)时提供了灵活的进制转换选项。 `strtol()` 函数的...
### strtoul 函数详解 #### 一、函数简介 `strtoul` 是 C 语言标准库中的一个函数,用于将字符串转换成无符号长整型数。它在 `<stdlib.h>` 头文件中定义。 #### 二、函数原型 ```c unsigned long int strtoul...
在本文档中,我们将介绍五种常用的类型转换函数:atoi、atol、strtod、strtol和strtoul。 一、atoi函数 atoi函数是将字符串转换为整型数的函数。它的函数原型为: ```c int atoi(const char *nptr); ``` 函数说明...
u-boot支持多种操作系统,如Linux、QNX、VxWorks等,并且可以支持多种处理器架构,包括ARM、PowerPC、X86等。 #### 知识点三:LCD驱动的添加与配置 本手册主要介绍了如何在u-boot 2010.06版本中为S3C2440处理器...
### 字符串处理中的常见问题 #### 一、概述 在C语言中,字符串处理是一项极为重要的技能。尽管C语言自身并不提供专门的字符串数据类型,但通过字符数组和指针,可以灵活地进行字符串的操作。本文将详细介绍C语言中...
在计算机科学领域,经常需要处理不同进制的数据转换问题。本篇文章主要介绍如何将字符串形式的数值转换为对应的数值类型,特别是针对十六进制字符串的转换方法。这种转换在编程语言中非常常见,涉及到的主要函数包括...
尽管dm9000在大多数情况下能够正常工作,但在某些情况下仍可能会遇到一些问题。以下是一些常见的问题及其解决方案: **问题1:** 网卡的MAC地址与配置的地址不一致。 **解决方案:** 修改`drivers/dm9000.c`中的`...
在文件的最后加入Nand Flash的初始化函数,该函数在后面Nand Flash的操作都要用到。 u-boot运行到第2阶段会进入start_armboot()函数。其中nand_init()函数是对nand flash的最 初初始化函数。nand_init()函数在两个...
1. 首先,我们需要清除流的基数设置,因为默认情况下`std::istringstream`会将输入视为十进制,`ss.clear();` 2. 创建一个`std::istringstream`对象,如`std::istringstream iss(hex_str);` 3. 设置流的基数为16,`...
本文档主要讲解如何在Linux环境下将物理地址转换为虚拟地址,以便于在用户空间中查看和修改寄存器的值。 首先,对于设备树(Device Tree)配置,它是Linux内核用来描述硬件结构的一种方式。在修改SDIO时钟驱动能力...
LINUX系统安全挖掘技术及其应用研究 本文档主要讨论了LINUX系统安全挖掘技术及其应用研究。安全分析是计算机系统安全的核心,防止未授权的访问和信息修改。...这些问题都是非常重要的,需要我们高度关注和研究。
6. **锁和同步**:DDI还包括了锁机制(`ddi_mutex_lock()`, `ddi_mutex_unlock()`)和同步机制(`ddi_spin_lock()`, `ddi_spin_unlock()`),这对于多线程环境下的驱动程序尤其重要。 #### DKI (Device Kernel ...
- `strtoul`、`strtol`:将字符串转换为无符号或带符号的长整型数值。 - `strupr`、`strlwr`:将字符串中的字符转换为大写或小写。 这些函数构成了C语言中强大的字符串处理工具箱,极大地简化了字符串的管理和操作...