Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C “隐式函数声明”与函数原始版本之间的差异_C_Linux_Sleep - Fatal编程技术网

C “隐式函数声明”与函数原始版本之间的差异

C “隐式函数声明”与函数原始版本之间的差异,c,linux,sleep,C,Linux,Sleep,我使用gcc4.8。我用睡眠编写了这样的代码 int main(int argc, char *argv[]) { /* I know it's worong to pass a floating number to sleep * this is only for testing. */ sleep(0.001); return 0; } 我用gcc-Wall a.c-oa编译它,得到函数'sleep'[-Wimplicit f

我使用gcc4.8。我用睡眠编写了这样的代码

int main(int argc, char *argv[])
{
    /* I know it's worong to pass a floating number to sleep
     * this is only for testing. */
    sleep(0.001);               
    return 0;
}
我用gcc-Wall a.c-oa编译它,得到函数'sleep'[-Wimplicit function declaration]的警告隐式声明。然后我运行它,这个程序睡眠大约1秒,似乎睡眠细胞是0.001到1

然后我将代码更改为如下所示:

#include <unistd.h> /* add header file */
int main(int argc, char *argv[])
{
    /* I know it's worong to pass a floating number to sleep
     * this is only for testing. */
    sleep(0.001);               
    return 0;
}
这一次它只睡0秒,好像睡0.001到0


这两个sleep不应该是相同的吗?

在第一种错误的情况下,为sleep提供了一个真正的浮点值,因为它假设sleep的原型实际使用了一个双精度浮点值。sleep会将这个double的位表示解释为int,并等待这么多秒。你很幸运,这仅仅是1秒。在第二种情况下,浮点值被强制转换为整数,舍入为0。

在第一种错误情况下,实际浮点值被赋予休眠,因为假定休眠原型的浮点值实际上是双精度的。sleep会将这个double的位表示解释为int,并等待这么多秒。你很幸运,这仅仅是1秒。在第二种情况下,浮点值被强制转换为整数,舍入为0。

IMHO,请始终使用-Werror=隐式函数声明编译选项,以防止编译器/链接器的智能默认行为造成损害

通过将这两个案例编译成两个可执行文件sleep_include_no1错误案例,无include和sleep_include_yes第二个ok案例,使用include,我做了一些简单的测试:

## 'sleep' will invoke the 'nanosleep', and use strace to show real duration
$ strace ./sleep_include_no 2>&1 | grep nanosleep
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0x7ffee0165970) = 0

$ strace ./sleep_include_yes 2>&1 | grep nanosleep
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=0}, 0x7ffce92eedd0) = 0
从gdb的disas命令的输出截取asm代码:


IMHO,请始终使用-Werror=隐式函数声明编译选项,以防止编译器/链接器的智能默认行为造成损害

通过将这两个案例编译成两个可执行文件sleep_include_no1错误案例,无include和sleep_include_yes第二个ok案例,使用include,我做了一些简单的测试:

## 'sleep' will invoke the 'nanosleep', and use strace to show real duration
$ strace ./sleep_include_no 2>&1 | grep nanosleep
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0x7ffee0165970) = 0

$ strace ./sleep_include_yes 2>&1 | grep nanosleep
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=0}, 0x7ffce92eedd0) = 0
从gdb的disas命令的输出截取asm代码:


所以第一种情况就像把无符号int和t相加;一开始,更可能是int-sleepdoult,因为传统上隐式声明总是返回int。这可以追溯到早期版本的C。因此第一种情况类似于添加无符号int-sleepdoult;一开始,更可能是int-t,因为传统上隐式声明总是返回int。这可以追溯到早期版本的C。
$ cat my_lib.h
#ifndef _my_lib_h_
#define _my_lib_h_
long long get_i64_from_my_lib(); 
#endif

$ cat my_lib.c
#include "my_lib.h"
long long get_i64_from_my_lib() {
        return 113840990519587; /* 6789 ABCD 0123 */
}

$ cat main.c 
#include <stdio.h>
/* #include "my_lib.h" (without this include, the result is buggy) */
int main() {
        long long i64 = get_i64_from_my_lib();
        printf("%lld, %0lx\n", i64, i64);
}

$ gcc -g -c my_lib.c
$ ar -cq my_lib.a my_lib.o
$ gcc -g -o my_exe main.c my_lib.a  ## emit implicit-function-declaration warning

## The returned type is not an expected i64, but a truncated i32. \
## When the returned value is less than 2^31, the function seems ok, \
## so it is an evil bug.
$ ./my_exe 
-1412628189, ffffffffabcd0123