线程 pthread_join 函数返回 void * 出现 -Wpointer-to-int-cast 告警

  最近学习多线程,写Demo程序时,遇到一个编译器告警,就是在用 pthread_join 函数获取线程返回状态值时,出现 -Wpointer-to-int-cast 告警。下面来看一下具体是啥问题

原 Demo 程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
void *func_1(void *);
void *func_2(void *);

int main() {
    pthread_t tid_1, tid_2;
    void *status;
    int err = pthread_create(&tid_1, NULL, func_1, NULL);
    assert(err == 0);
    err = pthread_create(&tid_2, NULL, func_2, NULL);
    assert(err == 0);
    
    err = pthread_join(tid_1, &status);
    assert(err == 0);
    printf("thread 1 exit status value is : %d\n", (int)status);
    err = pthread_join(tid_2, &status);
    assert(err == 0);
    printf("thread 2 exit status value is : %d\n", (int)status);
    return 0;
}
void *func_1(void *val) {
    pthread_t tid = pthread_self();
    printf("Thread 1: 0x%lx\n", (unsigned long)tid);
    return (void *)1;
}
void *func_2(void *val) {
    pthread_t tid = pthread_self();
    printf("Thread 2: 0x%lx\n", (unsigned long)tid);
    return (void *)2;
}

在用 gcc 编译时,告警如下:
编译器告警
分析原因:
先看下 pthread_join 函数原型如下:
int pthread_join(pthread_t thread, void **retval);

The pthread_join() function waits for the thread specified by thread to terminate.
If that thread has already terminated, then pthread_join() returns immediately.
The thread specified by thread must be joinable.

本人编译环境是64位,gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04),函数 pthread_join 返回值为 void * 类型大小 8 字节,在之后打印返回值 status 时,强制转换为 int (4 字节),故而产生该告警。

高版本gcc会产生编译告警,程序可正常执行。但是低版本gcc(4.0)不会编译告警,程序运行时会直接段错误 exit。
因此在使用 void * 做传参时,一定要注意参数类型大小。

解决方式:打印返回值 status 时,强制转换为 long (8字节)即可。

修改后的部分代码:

err = pthread_join(tid_1, &status);
assert(err == 0);
printf("thread 1 exit status value is : %ld\n", (long)status);
err = pthread_join(tid_2, &status);
assert(err == 0);
printf("thread 2 exit status value is : %ld\n", (long)status);

正常编译后,运行如下:
运行

posted @ 2020-04-19 10:54  Caso_卡索  阅读(361)  评论(0编辑  收藏  举报