On z/OS the pthread_t
type is a struct that contains a member char __[8];
. I tried to cast this from a return value to an int64_t
. I got following error:
CCN5216 (S) An expression of type "char [8]" cannot be converted to type "int64_t"
But if I use a temporary variable tmp
it works. I can compile this code with Visual Studio 2015 (defining a custom mypthread
struct similar to zos pthread_t
) without errors. Do you know why the xlc++ has a problem with this cast? Is the cast standard conform?
#define _OPEN_THREADS
#include <iostream>
#include <stdint.h>
#include <pthread.h>
pthread_t apr_os_thread_current() {
return pthread_t();
}
int64_t getId() {
pthread_t tmp = apr_os_thread_current();
return (int64_t) tmp.__; // ok
//return (int64_t) apr_os_thread_current().__; // CCN5216
//return reinterpret_cast<int64_t>(apr_os_thread_current().__); // CCN5216
}
int main() {
std::cout << getId() << std::endl;
return 0;
}
Without the temporary variable, the array is a part of an rvalue, which probably inhibits the implicit array-to-pointer conversion, requiring that char[8]
be reinterpreted as int64_t
directly.
Introducing the temporary variable (an lvalue) enables the array-to-pointer conversion on tmp.__
and then the pointer is cast to int64_t
without any "problem", actually returning a bogus value. In other words your working/compiling code is equivalent to the following:
return (int64_t) &tmp.__[0]; // ok ???
This is only a hypothesis that you can check as follows:
int64_t getId() {
pthread_t tmp = apr_os_thread_current();
int64_t result = (int64_t) tmp.__;
if ( result == (int64_t) &tmp.__[0] )
std::cerr << "oops!" << std::endl;
return result;
}