Рассмотрим функции типа localtime
в стандартной библиотеке C, которые возвращают указатель на (исторически) статический буфер. Делает ли C11 эти буферы локальными для потока?
Согласно 7.1.4 в С11:
Если в приведенных ниже подробных описаниях явно не указано иное, библиотечные функции должны предотвращать гонки данных следующим образом: библиотечная функция не должна прямо или косвенно обращаться к объектам, доступным для потоков, отличных от текущего потока, если к объектам не осуществляется прямой или косвенный доступ через аргументы функции. Библиотечная функция не должна прямо или косвенно изменять объекты, доступные для потоков, отличных от текущего потока, если к объектам не осуществляется прямой или косвенный доступ через неконстантные аргументы функции. Реализации могут делиться своими внутренними объектами между потоками, если объекты не видны пользователям и защищены от скачек данных.
Рассмотрим для примера localtime
. struct tm
, на который указывает его возвращаемое значение, не относится к «внутреннему объекту», так как он доступен для вызывающей стороны, поэтому кажется, что вызов localtime
в другом потоке может не засорять результат, ранее возвращенный в первая нить Это означало бы, что localtime
необходимо использовать разные буферы для каждого потока.
Однако в стандарте нигде не указывается конец времени жизни объекта, адрес которого возвращается, и я не вижу причин, по которым программа, продолжающая использовать этот struct tm
после завершения вызывающего потока, была бы недействительной. Таким образом, объект не может иметь длительность хранения потока.
Единственный способ обнаружить, что реализация может удовлетворить все требования, - это утечка памяти повсюду, что, безусловно, не то, что предполагалось. Я что-то упускаю из виду или обработка C11 безопасности потоков в отношении устаревших интерфейсов действительно настолько плохо продумана?