Безопасность потока сообщений MSVC

Является ли errno в MSVC потокобезопасным?

В соответствии с ответами в этом вопросе POSIX требует, чтобы errno был потокобезопасным. Но MSVC, вероятно, не совместим с POSIX и MSDN ничего не говорит о безопасности потоков. MSDN противоречиво упоминает, что errno объявлен как extern int errno;, но также как #define errno (*_errno())

Ответ 1

Хотя MSVC определенно не совместим с POSIX, errno реализуется в среде выполнения MSVC (по крайней мере, с MSVC2008) в потоковом режиме.

Несмотря на то, что в документации указано, что она extern int errno, она фактически реализована как #define для функции, которая позволяет навязывать потоки. Если вы выполните эту функцию в окне разборки, ясно, что используется локальное хранилище потоков.

К сожалению, я не могу указать на официальную документацию, подтверждающую это, но это жизнь!

Ответ 2

Я не могу найти нигде на сайте MSDN, где это обсуждается. Однако многие функции, которые возвращают статические буферы, уже являются потокобезопасными в MSVC (т.е. Возвращают указатели на потоковые локальные буферы). Поэтому было бы удивительно, если бы errno не был потокобезопасным.

Все файлы заголовков MSVC имеют следующее определение:

#ifndef _CRT_ERRNO_DEFINED
#define _CRT_ERRNO_DEFINED
_CRTIMP extern int * __cdecl _errno(void);
#define errno   (*_errno())

errno_t __cdecl _set_errno(_In_ int _Value);
errno_t __cdecl _get_errno(_Out_ int * _Value);
#endif  /* _CRT_ERRNO_DEFINED */

И небольшая тестовая программа показала, что 2 потока, устанавливающие errno, по крайней мере не влияют друг на друга. Поэтому я бы сказал, что безопасно предположить, что errno является потокобезопасным (хотя, вероятно, нет, если вы ссылаетесь на единственный поток CRT)