先看下面的两个程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//----a.c
#include <stdio.h>
#include <stdlib.h>

int atoi(const char* ptr)
{

printf("haha:%s\n", ptr);
return 0;
}

int main()
{

const char* ptr = "12";
int ret = atoi(ptr);
return 0;
}
1
2
3
编译:gcc -o a.o a.c
执行:./a.o
结果:haha:12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//----b.c
#include <stdio.h>
#include <stdlib.h>

int atoi(const char* ptr)
{

printf("haha:%s\n", ptr);
return 0;
}

int main()
{

const char* ptr = "12";
atoi(ptr);
return 0;
}
1
2
3
编译:gcc -o b.o b.c
执行:./b.o
结果:(空)

为什么会出现这个现象。

将两个程序分别汇编

查看汇编代码,发现b.c汇编后的结果并没有调用atoi这个函数(glibc中和自己实现的都没有调用),可能是atoi被优化掉了。

查看glibc中atoi的声明

1
2
3
4
5
6
7
8
9
10
11
12
/usr/include/stdlib.h
extern int atoi (__const char *__nptr)
__THROW __attribute_pure__ __nonnull ((1)) __wur;
__attribute_pure__是一个宏

/usr/include/cdefs.h
#if __GNUC_PREREQ (2,96)
# define __attribute_pure__ __attribute__ ((__pure__))
#else
# define __attribute_pure__ /* Ignore */
#endif
当gcc版本大于2.96时,__attribute_pure__ 转化为__attribute__ ((__pure__))

查看gcc文档

Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute pure. For example,

int square (int) attribute ((pure));

says that the hypothetical function square is safe to call fewer times than the program says.
Some of common examples of pure functions are strlen or memcmp. Interesting non-pure functions are functions with infinite loops or those depending on volatile memory or other system resource, that may change between two consecutive calls (such as feof in a multithreading environment).

The attribute pure is not implemented in GCC versions earlier than 2.96.
大致意思是这个函数这个函数没有付作用,当不需要它的返回值时,它可以被优化掉,但是我们自己的实现中是有打印输出的,所以造成声明和实现不一致。所有在第二个程序中,我们没有用到它的返回值,所以这个函数直接被删除掉了,才会出现上面的结果。

Comments

2012-06-21