Нет, это не заказ.Это тип из retval
.Когда, передавая &retval
в pthread_join
, это неправильный тип / sizeof.
Когда retval
является int
, это только 4 байта, но [при условии 64-битной компиляции], pthread_join
ожидает указатель на void *
, что составляет 8 байтов.
Это вызывает неопределенное поведение, потому что вызов записывает 8 байтов в переменную, которая составляет всего 4 байта.Оставшиеся 4 байта превышают размер retval
и могут перезаписывать что угодно в стеке.
В вашем втором примере было то же неопределенное поведение, но нам просто «повезло»и получил ожидаемый результат [вероятно, потому что порядок переменных в кадре стека изменился, чтобы избежать выдачи UB неожиданного результата].Но у обоих все еще было UB.
Кроме того, при приведении к / от указателя мы должны использовать long
вместо int
[для предотвращения предупреждений компилятора].
Вот исправленноекод:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define THREADS 4
void *
routine1(void *x)
{
#if 0
int result = 2;
#else
long result = 2;
#endif
pthread_exit((void *) result);
}
int
main()
{
int sum = 0;
#if 0
int retval = 0;
#else
void *retval;
#endif
pthread_t threads[THREADS];
#if 0
for (int i = 0; i < THREADS; i++)
pthread_create(&threads[i], NULL, routine1, (void *) i);
#else
for (long i = 0; i < THREADS; i++)
pthread_create(&threads[i], NULL, routine1, (void *) i);
#endif
for (int i = 0; i < THREADS; i++) {
pthread_join(threads[i], &retval);
#if 0
sum += retval;
#else
sum += (long) retval;
#endif
}
printf("%d\n", sum);
return 0;
}