最近学习多线程,写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);
正常编译后,运行如下: