2

Suppose the following code:

pthread_key_t key;
pthread_key_create(&key, NULL);    /* failure here */
pthread_key_delete(key);

If pthread_key_create fails, is the call to pthread_key_delete considered undefined behavior? How about if pthread_key_create is commented out?

The pthread_key_delete section of the POSIX standard states:

The pthread_key_delete() function shall delete a thread-specific data key previously returned by pthread_key_create().

Since pthread_key_delete expects a thread-specific data key previously returned by pthread_key_create, I'm afraid calling pthread_key_delete on a key that was not returned by pthread_key_create can lead to undefined behavior.

Vilhelm Gray
  • 11,516
  • 10
  • 61
  • 114

2 Answers2

3

Yes, it is implicitly undefined behavior, to the extent that the standard you link doesn't define what happens in that use case.

The SUSv7, however, is explicit in its discussion of pthread_key_delete, saying plainly in its CHANGE HISTORY for Issue 7 that:

The [EINVAL] error for a key value not obtained from pthread_key_create() or a key deleted with pthread_key_delete() is removed; this condition results in undefined behavior.

pilcrow
  • 56,591
  • 13
  • 94
  • 135
  • Oh dear, I just realized I read the older *Issue 6* whereas I had intended to read the more current *Issue 7*. I must keep a watchful eye next time. – Vilhelm Gray Aug 07 '13 at 18:24
  • @VilhelmGray, fair enough. I'd argue that it's the same undefined behavior in either, just that SUSv7 is more explicit about it. – pilcrow Aug 07 '13 at 18:29
  • Yes, I believe that probably factored into the decision to explicitly state there is undefined behavior in such cases. – Vilhelm Gray Aug 07 '13 at 18:44
2

By looking at the source code of pthread_key_create and pthread_key_delete it seems that pthread_key_create is returning a memory location and filling in other fields of "key" structure, which is opaque like everything else in posix.

pthread_key_delete expects the key structure fields to be populated/set with valid data to search for the memory location. So it seems calling pthread_key_delete after a failed pthread_key_create causes undefined behavior. Here is one more link that seems to support by opinion.

How does pthread_key_t and the method pthread_key_create work?

I hope this helps.

Community
  • 1
  • 1
O.C.
  • 6,711
  • 1
  • 25
  • 26
  • The source base you selected as example might not be the most widly spread implemention of Pthread in terms of usage, wouln't it? – alk Aug 07 '13 at 16:53
  • Also, the code for `pthread_key_delete()` linked does not fully comply with the POSIX specification. For example it will not return `EINVAL` if a zeroed out `pthread_key_t` key had been passed in, nor if the key had not been found. – alk Aug 07 '13 at 16:58
  • Below you can see two more examples for pthread_key_delete.c http://code.mjdsystems.ca/p/equalizer/source/tree/580548b8250b734cdad16caaa0b47d4916ea21c9/Windows/pthreads/src/pthread_key_delete.c and ftp://sourceware.org/pub/pthreads-win32/sources/pthreads-w32-2-9-1-release/pthread_key_delete.c None of them return EINVAL. However, there are some implementations that do return EINVAL. For instance : http://cristi.indefero.net/p/uClibc-cristi/source/tree/0949826e9501e9f08767aeb476ea1464bf95f218/libpthread/nptl/pthread_key_delete.c So, this proves that behaviour is "undefined". – O.C. Aug 07 '13 at 18:20
  • For `eglibc` the behaviour would be defined and `EINVAL` would be returned. No key would provoke UB. However, I do agree that do calling `pthread_key_delete()` on an undefined key is a bad idea, although the standard (as linked by my answer) does not explicitly mentions this. – alk Aug 07 '13 at 18:39
  • 2
    I'm skeptical of the appropriateness of looking at any implementation to determine whether a usage is undefined behavior or not. Whether or not the behavior is undefined has everything to do with the specification of behaviors and not their particular implementations. – pilcrow Aug 07 '13 at 18:42
  • @pilcrow i agree. looking at the implementation was my last resort, since it was not mentioned explicitely. – O.C. Aug 07 '13 at 18:48
  • @pilcrow: Agreed! However, it is interesting to see how implementations differ ... – alk Aug 07 '13 at 19:06