陷入困境(1)

时间:2013-01-15 15:01:06

标签: c gcc c99

我的程序卡在简单的调用usleep(1.);中。怎么可能?我应该注意什么?

修改

为了让事情变得更加混乱,只有在我之前调用rand()之前它才会被卡住:

rand();
usleep(1.);

两个电话都很好。

编辑2:

这是一个有效的最小例子:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
        printf("Calling rand() and then usleep(1) on pid %d \n",getpid());
        rand();
        usleep(1);
        printf("Finished.\n");
        return 0;
}

这个也有效:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
        printf("Calling usleep(1.) on pid %d \n",getpid());
        usleep(1.);
        printf("Finished.\n");
        return 0;
}

但是,这个没有:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
        printf("Calling rand() and then usleep(1.) on pid %d \n",getpid());
        rand();
        usleep(1.);
        printf("Finished.\n");
        return 0;
}

我使用命令gcc -std=c99 main.c使用gcc版本4.4.6编译它们。选项-std=c99是问题吗?但我仍然不明白这里发生了什么。

3 个答案:

答案 0 :(得分:5)

您使用usleep()值调用double,而指定采用范围有限的useconds_t类型的无符号整数。请参阅the manual page

在您的平台上,转换可能会失败。请尝试删除期间,然后使用1调用它。

不要引入演员表,最好不要提及useconds_t类型。

另请注意,此功能已过时,新的POSIX代码应使用nanosleep()代替。

更新顺便说一句,上面链接的手册页似乎也暗示您应该#define #include <unistd.h>之前列出的正确符号来获得此功能。您应该尝试一下,如果您没有获得原型,参数将不会自动从double转换。来自rand()的(被忽略的)返回值也可能在某个寄存器或堆栈中,导致在这种情况下进一步改变。

答案 1 :(得分:2)

来自myleep http://www.manpagez.com/man/3/usleep/的手册页,usleep的输入参数为useconds_t,而不是float,如代码中所示

答案 2 :(得分:0)

我尝试了一些事情。

  1. rand(); printf也没有什么特别之处。以下内容还显示了此行为(它在说“正在启动”后挂起),但如果第一个printf()被注释掉,则程序完成。

    include <stdio.h>
    include <unistd.h>
    
    void main(int argc, char* argv[]) {
        printf ("Starting\n"); 
        usleep(10.1);
        printf("Finished.\n");
    }
    
  2. 如果使用-std=gnu89(或gnu99)而不是-std=c89(或c99)进行编译,则您的程序始终有效。

  3. -o0到-o3的各种排列没有区别。

  4. usleep需要一个int,而不是一个浮点数。如果你明确地投了它,即usleep((int)10.1),程序就不会挂起。

  5. 打开警告(-Wall -Wextra -Wconversion)会抱怨隐含声明usleep