coanor
coanor

Reputation: 3962

What is the difference between `#include` and `extern` while import a extern variable to local?

While using the errno, I once read words that

It is important to include errno.h rather than providing your own extern int errno, since errno is implemented in a thread-safe manner that is more than just a simple global int.

How does the thread-safe manner impact the difference between #include and extern ?

Upvotes: 2

Views: 950

Answers (4)

Martin Beckett
Martin Beckett

Reputation: 96139

It's not the extern vs #include that matters

errno is defined in the header as

int*    _errno(void);
#define errno       (*_errno())

Each thread has it's own errno in it's own address space

Upvotes: 4

Matthias
Matthias

Reputation: 8180

At least at mysystem, it is defined as #define errno (*__error()), i.e., it is calculated be errorwhich returns a pointer to the correct result. In this way, you could implement a thread safe errno.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

The quoted doc warns you that you should not assume that errno is implemented as

extern int errno;

in the <errno.h> header, that's all.

Obviously, an include file may contain things other than extern in it; in this case, the implementors took precautions to make errno behave in thread-safe way, but that's an unnecessary detail. The truly must-know thing is that you must include errno.h.

If you are really curious about the details, bring up your errno.h in an editor, and take a look. However, you need to remember that implementations on other systems may (and often will) be different.

Upvotes: 2

Vincenzo Pii
Vincenzo Pii

Reputation: 19835

In POSIX.1, errno is defined as an external global variable. But this definition is unacceptable in a multithreaded environment, because its use can result in nondeterministic results. The problem is that two or more threads can encounter errors, all causing the same errno to be set. Under these circumstances, a thread might end up checking errno after it has already been updated by another thread.

To circumvent the resulting nondeterminism, POSIX.1c redefines errno as a service that can access the per-thread error number as follows (ISO/IEC 9945:1-1996, §2.4):

Some functions may provide the error number in a variable accessed through the symbol errno. The symbol errno is defined by including the header , as specified by the C Standard ... For each thread of a process, the value of errno shall not be affected by function calls or assignments to errno by other threads.

In addition, all POSIX.1c functions avoid using errno and, instead, return the error number directly as the function return value, with a return value of zero indicating that no error was detected. This strategy is, in fact, being followed on a POSIX-wide basis for all new functions.

http://www.unix.org/whitepapers/reentrant.html

Upvotes: 3

Related Questions