Что произойдет, если 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?

Надеюсь, это поможет.

Другие вопросы по тегам