Что означает часть SYNOPSIS в man-странице perror? - PullRequest
0 голосов
/ 28 февраля 2020

раздел SYNOPSIS в справочной странице perror :

   #include <stdio.h>

   void perror(const char *s);

   #include <errno.h>

   const char * const sys_errlist[];
   int sys_nerr;
   int errno;       /* Not really declared this way; see errno(3) */

в соответствии с спецификацией man-страницы , раздел SYNOPSIS указывает, что

Для функций отображаются все необходимые объявления данных или директивы #include, после которых следует объявление функции.

Следующий код:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *ls_args[2] = {"nonsense", NULL};
    execv(ls_args[0], ls_args); // no return
    perror("execve failed");
    return 2;
}

выводит сообщение об ошибке execve failed: No such file or directory, с соответствующим errno, равным 2

, поскольку errno является глобальной переменной (на самом деле макрос), определенной в errno.h, а заголовок errno.h не включен, как это сделать код запуска errno модификация?

Что означает #include <errno.h> ... int errno; в разделе ОПИСАНИЕ? похоже, что perror() можно вызвать без этой части кода, спасибо!

1 Ответ

2 голосов
/ 28 февраля 2020

Согласно стандарту C макрос errno объявлен в errno.h, и вы должны явно указать errno.h, если хотите написать переносимую программу, которая использует errno. Об этом говорится в справочном руководстве. (Это не говорит о том, что вам нужно включить errno.h, чтобы использовать perror. Иногда в разделе «Синопсис» рассказывается о других связанных библиотечных возможностях.)

Ничто в стандарте не определяет, что такое определение Макрос errno находится или где именно в реализации вы можете найти любые объекты, на которые ссылается расширение этого определения. Реализация perror, очевидно, должна иметь возможность доступа к любому объекту, на который ссылается errno, но, поскольку он не должен быть переносимым, совершенно не определено, как это работает.

В частности, последние стандарты C требуют, чтобы объект errno ссылался на локальный поток , чтобы каждый поток имел свой собственный объект errno. (Если бы это было не так, механизм был бы по существу непригодным для многопоточного кода.) Точная реализация локального хранилища потока также не определена стандартом, и в конкретной реализации он может быть отображен на некоторое средство, предоставляемое базовая операционная система.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...