On 05/03/2013 4:16 AM, 최영일 wrote:
> 
> I am investigating libc.rs
> 
> libc::types::common::c95::...
> libc::types::common::posix88::...
> 
> where these naming convention hierachy comes from ?
> and what is the difference between c95, posix01, posix88 ?

There's a large block comment at the top of the file that explains the
source documents. The names are picked as abbreviations for the full
document names:

c95 ==
"ISO 9899:1990 ('C95', 'ANSI C', 'Standard C'), NA1, 1995."
(note: NA1 -- "normative annex #1" -- was approved in 1995)

posix88 ==
"ISO 9945:1988 / IEEE 1003.1-1988 ('POSIX.1')."

posix01 ==
"ISO 9945:2001 / IEEE 1003.1-2001 ('POSIX:2001', 'SUSv3')."

and so forth. bsd44 is, as the comment mentions, a collection of
auxiliary material that roughly corresponds to the 4.4 BSD release that
is the source of most BSD-derived unixes we see today.

The point of the module hierarchy in libc.rs is to make it somewhat
reasonable for a single over-taxed maintainer (me) to read through
standards documents and reference manuals and write down what I see in
those documents, _then_ go to each platform and look for the
corresponding definitions in each header file or reference manual.

The alternative strategy is to start from the header files I find on a
given platform and transcribe "everything", trying to guess which
features are enabled or disabled on which versions or flags, which
features are mandatory or optional, which conform to standards or
deviate from them, etc. This latter strategy was how I initially
approached writing libc interfaces, and it was very difficult, as each
symbol in each operating system header (at this low level) is guarded by
multiple CPP ifdef-guards and frequently several levels of indirect
typedefs and inclusions of many additional files. It gets quite
difficult to tell "which symbols actually exist, or are supposed to
exist, on each platform", and to what degree their current values are
accidental or defined by-reference to some other value that is the
more-normative / more platform-agnostic / more arch-agnostic one.

It's much easier (in my experience so far) to understand each platform
and architecture in terms of "figuring out which standards the platform
claims to conform to and how it depends on its arch", and then picking
out the definitions _for those standards_, usually one at a time. It is
also much easier (IME so far) to split apart the 3 separate categories
within each standard:

  1. "things that vary by OS"
  2. "things that vary by architecture, even within a single OS"
  3. "things that are OS and architecture neutral"

and avoid duplicating definitions when possible. Notice for example that
the constants tend to be architecture neutral and a great many of the
functions are both OS and architecture neutral (though not all -- this
varies by spec).

It also makes it more reasonable for the libc _user_ (not usually a
direct rust programmer, but a higher-level abstraction module such as
os.rs) to write code to interfaces that are "more widely available" by
picking modules in libc that are older and more widely supported. For
example, writing to the c95 module _alone_ will guarantee a program can
run on windows and linux. This is surprising, but true: windows actually
supports the full c95 spec worth of interfaces in their msvcrt.dll
runtime library. They do _not_ support most of the rest of the bsd or
posix interfaces. Only a random subset (with many symbols doing
"slightly different things" than in posix).

So far, despite the organization being _cluttered_ -- which I freely
admit, it's a bit overwhelming at first -- I've found this organization
of libc to be much much easier to _maintain_ and get _correct_ than the
alternative we had before, of "one module for each OS containing all
definitions". In that case we had lots of both duplication, missing
definitions and simple _bugs_ / incorrect definitions between modules.

-Graydon

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to