1

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;
}
Christian Ammer
  • 7,464
  • 6
  • 51
  • 108

1 Answers1

1

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;
}
Christian Ammer
  • 7,464
  • 6
  • 51
  • 108
Leon
  • 31,443
  • 4
  • 72
  • 97
  • Yes, you are right: The output is "oops! 515113908" – Christian Ammer Jan 27 '17 at 12:09
  • This works: `return *((int64_t*)&apr_os_thread_current().__[0]);` – Christian Ammer Jan 27 '17 at 12:18
  • Why do you want to convert an opaque structure to an int64_t? The z/OS pthread_t is actually two intergers, a sequence number and a pointer to the thread control block (TCB -Task Control Block). The only reason I've done that in the past is to print the TCB in a log. – David Crayford Jan 30 '17 at 12:50