Что произойдет, если pthread_key_delete вызывается для ключа после неудачного pthread_key_create?
Предположим, следующий код:
pthread_key_t key;
pthread_key_create(&key, NULL); /* failure here */
pthread_key_delete(key);
Если pthread_key_create
не удается, это вызов pthread_key_delete
считается неопределенным поведением? Как насчет, если pthread_key_create
закомментировано?
Раздел pthread_key_delete стандарта POSIX гласит:
Функция pthread_key_delete() должна удалить специфичный для потока ключ данных, ранее возвращенный pthread_key_create().
поскольку pthread_key_delete
ожидает специфический для потока ключ данных, ранее возвращенный pthread_key_create
Боюсь звонить pthread_key_delete
на ключ, который не был возвращен pthread_key_create
может привести к неопределенному поведению.
2 ответа
Да, это неявно неопределенное поведение в той степени, в которой стандарт, на который вы ссылаетесь, не определяет, что происходит в этом случае использования.
SUSv7, однако, явно в своем обсуждении pthread_key_delete
, прямо говоря в своей ИСТОРИИ ИЗМЕНЕНИЯ для проблемы 7, что:
Ошибка [EINVAL] для значения ключа, не полученного из pthread_key_create(), или ключа, удаленного с помощью pthread_key_delete(), удаляется; это условие приводит к неопределенному поведению.
Глядя на исходный код pthread_key_create и pthread_key_delete, кажется, что pthread_key_create возвращает место в памяти и заполняет другие поля структуры "ключ", которая непрозрачна, как и все остальное в posix.
pthread_key_delete ожидает, что поля структуры ключа будут заполнены / установлены с правильными данными для поиска места в памяти. Поэтому кажется, что вызов pthread_key_delete после сбоя pthread_key_create вызывает неопределенное поведение. Вот еще одна ссылка, которая, кажется, поддерживает мнение.
Как работает pthread_key_t и метод pthread_key_create?
Надеюсь, это поможет.