• Re: _BitInt(N)

    From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Sat Dec 20 11:24:00 2025
    From Newsgroup: comp.lang.c

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    bart <bc@freeuk.com> wrote:

    On 28/11/2025 23:23, Keith Thompson wrote:

    bart <bc@freeuk.com> writes:

    On 28/11/2025 02:33, Janis Papanagnou wrote:

    [...]
    You can of course add as many commodity features to "your
    language" as you like. I seem to recall that one of the design
    principles of "C" was to not add too many keywords. (Not sure
    whether 'A.odd' is a function or keyword above [in "your
    language"].)

    It is a reserved word, which means it can't be used as either a
    top-level user identifier, or a member name. With extra effort,
    it could be used for both, but that needs some special syntax,
    such as Ada-style "A'odd"; I've never got around to it.

    In Pascal (where I copied it from) it is a reserved word.

    <OT>In Pascal, "odd" is not a reserved word. It's the name of a
    predefined function.</OT>

    So what's a 'reserved word' then? To me it is something not
    available as a user-identifier because it has a special meaning in
    the language,

    That's a general description, but at least in C, there's several
    different kinds of reserved identifiers, each kind specifies
    different restrictions on user code use of that identifier.

    Note: in C2023, the [predefined macro names] section says: "Any other predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such identifiers because they were reserved for all purposes, but that's no
    longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use
    them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then
    unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    Note by the way that the description in N3220 section 6.10.10.1
    paragraph 2 makes using #define or #undef be undefined behavior only
    for macro names in the subclause (and also a short list of other
    identifiers). Hence any other predefined macro name may be used,
    definedly, simply by using #undef and then #define for the macro
    name in question (in particular, under C23 rules, but not earlier
    versions of the C standard).
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.lang.c on Sun Dec 21 00:18:16 2025
    From Newsgroup: comp.lang.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    bart <bc@freeuk.com> wrote:

    On 28/11/2025 23:23, Keith Thompson wrote:

    bart <bc@freeuk.com> writes:

    On 28/11/2025 02:33, Janis Papanagnou wrote:

    [...]
    You can of course add as many commodity features to "your
    language" as you like. I seem to recall that one of the design
    principles of "C" was to not add too many keywords. (Not sure
    whether 'A.odd' is a function or keyword above [in "your
    language"].)

    It is a reserved word, which means it can't be used as either a
    top-level user identifier, or a member name. With extra effort,
    it could be used for both, but that needs some special syntax,
    such as Ada-style "A'odd"; I've never got around to it.

    In Pascal (where I copied it from) it is a reserved word.

    <OT>In Pascal, "odd" is not a reserved word. It's the name of a
    predefined function.</OT>

    So what's a 'reserved word' then? To me it is something not
    available as a user-identifier because it has a special meaning in
    the language,

    That's a general description, but at least in C, there's several
    different kinds of reserved identifiers, each kind specifies
    different restrictions on user code use of that identifier.

    Note: in C2023, the [predefined macro names] section says: "Any other
    predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no
    longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use
    them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    Hmm, looking at '/usr/include/string.h' on my machine I see definitions
    of things like

    __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
    __need_size_t

    and lot of similar things. I do not recall seeing any user
    documentation listing them. Does this mean that gcc+glibc
    is noncompilant in this aspect?
    --
    Waldek Hebisch
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Sat Dec 20 18:22:11 2025
    From Newsgroup: comp.lang.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    [...]
    Note: in C2023, the [predefined macro names] section says: "Any other
    predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no
    longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use
    them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    Note by the way that the description in N3220 section 6.10.10.1
    paragraph 2 makes using #define or #undef be undefined behavior only
    for macro names in the subclause (and also a short list of other identifiers). Hence any other predefined macro name may be used,
    definedly, simply by using #undef and then #define for the macro
    name in question (in particular, under C23 rules, but not earlier
    versions of the C standard).

    I don't *think* that all implementation-specific predefined macros have
    to be documented -- at least, I'd be surprised if that were the intent.

    For example, I don't think an implementation is required to document its
    use of _STDIO_H (the include guard header in the glibc implementation of <stdio.h>).

    Though it's not normative, N3220 J.5.1 (Common extensions) says:

    Examples of such extensions are new keywords, extra library
    functions declared in standard headers, or predefined macros with
    names that do not begin with an underscore.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From James Kuyper@jameskuyper@alumni.caltech.edu to comp.lang.c on Sat Dec 20 21:27:31 2025
    From Newsgroup: comp.lang.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    ...
    Note: in C2023, the [predefined macro names] section says: "Any other
    predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no
    longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use
    them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    J.5 identifies as extensions only "... predefined macros with names that
    do not begin with an underscore." (J.5, J.5.13) They are not identified
    as implementation-defined, so there is no obligation to document them.
    Portable code must,of course simply avoid all such identifiers.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@046-301-5902@kylheku.com to comp.lang.c on Sun Dec 21 02:27:59 2025
    From Newsgroup: comp.lang.c

    On 2025-12-20, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    identifiers). Hence any other predefined macro name may be used,
    definedly, simply by using #undef and then #define for the macro
    name in question (in particular, under C23 rules, but not earlier
    versions of the C standard).

    If that interpretation is accurate, it is a serious problem.

    The implementation must be prepared for the situation that any of its
    internal macros are undefined, or undefined and redefined.

    That means that other macros cannot rely on those macros.
    Some documented macro foo() cannot rely on a __foo_impl()
    macro because the program could #undef that.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Sun Dec 21 22:24:40 2025
    From Newsgroup: comp.lang.c

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    Richard Heathfield <rjh@cpax.org.uk> writes:

    On 02/12/2025 23:33, Keith Thompson wrote:

    [...]

    But trigraphs have been removed in C23.

    Then so, in some mainframe environments, have curly braces. I suppose
    their fix will be to not adopt C23.

    Curly braces are still available by means of the digraphs <% and %>.

    True, and that's probably good enough, but digraphs aren't recognized
    in string literals, character constants, header names, or comments.

    Comments are irrelevant because they aren't translated; if someone
    wants to use trigraphs (or digraphs) for curly braces inside a
    comment they are perfectly free to do so.

    Header names can be handled by copying or linking the file with a
    new name, where the new name has <% and %> in place of curly braces.

    String literals and character constants are a mild inconvenience,
    but nothing more than that - just four #define of symbols with
    appropriate values. Once those values are determined it should be straightforward to effect the necessary changes programmatically.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Sun Dec 21 22:48:57 2025
    From Newsgroup: comp.lang.c

    Kaz Kylheku <046-301-5902@kylheku.com> writes:

    On 2025-12-20, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    identifiers). Hence any other predefined macro name may be used,
    definedly, simply by using #undef and then #define for the macro
    name in question (in particular, under C23 rules, but not earlier
    versions of the C standard).

    If that interpretation is accurate, it is a serious problem.

    Yes, very serious. I suspect the change is simply an oversight
    on the part of those responsible for the wording in the C23
    standard.

    The implementation must be prepared for the situation that any of its internal macros are undefined, or undefined and redefined.

    That means that other macros cannot rely on those macros.
    Some documented macro foo() cannot rely on a __foo_impl()
    macro because the program could #undef that.

    Probably there are other ways to work around the problem,
    but it does seem better just to avoid the problem altogether
    by forbidding definitions (or #undef) of any reserved
    identifiers, including macro names.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Sun Dec 21 23:07:55 2025
    From Newsgroup: comp.lang.c

    antispam@fricas.org (Waldek Hebisch) writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    bart <bc@freeuk.com> wrote:

    On 28/11/2025 23:23, Keith Thompson wrote:

    bart <bc@freeuk.com> writes:

    On 28/11/2025 02:33, Janis Papanagnou wrote:

    [...]

    You can of course add as many commodity features to "your

    language" as you like. I seem to recall that one of the design
    principles of "C" was to not add too many keywords. (Not sure
    whether 'A.odd' is a function or keyword above [in "your
    language"].)

    It is a reserved word, which means it can't be used as either a
    top-level user identifier, or a member name. With extra effort,
    it could be used for both, but that needs some special syntax,
    such as Ada-style "A'odd"; I've never got around to it.

    In Pascal (where I copied it from) it is a reserved word.

    <OT>In Pascal, "odd" is not a reserved word. It's the name of a
    predefined function.</OT>

    So what's a 'reserved word' then? To me it is something not
    available as a user-identifier because it has a special meaning in
    the language,

    That's a general description, but at least in C, there's several
    different kinds of reserved identifiers, each kind specifies
    different restrictions on user code use of that identifier.

    Note: in C2023, the [predefined macro names] section says: "Any other
    predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no
    longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use
    them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then
    unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    Hmm, looking at '/usr/include/string.h' on my machine I see definitions
    of things like

    __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
    __need_size_t

    and lot of similar things. I do not recall seeing any user
    documentation listing them. Does this mean that gcc+glibc
    is noncompilant in this aspect?

    I think it's reasonable to say that the appearance of a macro
    name being #define'd in a standard header qualifies as
    documenting the name being #define'd. As long as the #define is
    readable in an ordinary source file, there isn't any mystery
    about the name being used or what its definition is. I suppose
    that to satisfy the letter of the C standard, the accompanying
    document would need to incorporate the system header files by
    reference, but surely the header files satisfy the spirit of
    providing the required documentation. Implementation-defined
    values for things like CHAR_BIT and INT_MAX fall under the same
    rule for documentation as do extensions, yet as far as I know
    these values are defined only in system header files, and not in
    any separate document.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Mon Dec 22 02:51:04 2025
    From Newsgroup: comp.lang.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    antispam@fricas.org (Waldek Hebisch) writes:
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    [...]
    Note: in C2023, the [predefined macro names] section says: "Any other >>>> predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no >>>> longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use >>>> them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then
    unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    Hmm, looking at '/usr/include/string.h' on my machine I see definitions
    of things like

    __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
    __need_size_t

    and lot of similar things. I do not recall seeing any user
    documentation listing them. Does this mean that gcc+glibc
    is noncompilant in this aspect?

    I think it's reasonable to say that the appearance of a macro
    name being #define'd in a standard header qualifies as
    documenting the name being #define'd.

    I disagree. I don't think it's reasonable to say that.

    Headers are not documentation. They're often barely human-readable,
    and the system headers aren't necessarily even files.

    As long as the #define is
    readable in an ordinary source file, there isn't any mystery
    about the name being used or what its definition is.

    System headers can be arbitrarily complex, with #includes for other system-specific headers, nests of #ifs and #ifdefs, and so on.

    I suppose
    that to satisfy the letter of the C standard, the accompanying
    document would need to incorporate the system header files by
    reference, but surely the header files satisfy the spirit of
    providing the required documentation. Implementation-defined
    values for things like CHAR_BIT and INT_MAX fall under the same
    rule for documentation as do extensions, yet as far as I know
    these values are defined only in system header files, and not in
    any separate document.

    gcc's documentation does have a "C Implementation-Defined Behavior"
    section. It doesn't mention CHAR_BIT by name, but it does document
    "The number of bits in a byte" as "Determined by ABI". I didn't
    find anything similar for INT_MAX.

    I find it implausible that the standard intended to require
    implementations to document all macros defined in standard headers,
    for example _STDIO_H, the include guard macro for <stdio.h> in glibc.

    C17 says:

    All identifiers that begin with an underscore and either an
    uppercase letter or another under- score are always reserved for
    any use, except those identifiers which are lexically identical
    to keywords.

    C23 dropped that wording. I'm not convinced that all the
    implications of that change were resolved properly (but I haven't
    studied it thoroughly).
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@046-301-5902@kylheku.com to comp.lang.c on Mon Dec 22 19:23:42 2025
    From Newsgroup: comp.lang.c

    On 2025-12-22, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    antispam@fricas.org (Waldek Hebisch) writes:
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    [...]
    Note: in C2023, the [predefined macro names] section says: "Any other >>>>> predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no >>>>> longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use >>>>> them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then
    unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    Hmm, looking at '/usr/include/string.h' on my machine I see definitions
    of things like

    __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
    __need_size_t

    and lot of similar things. I do not recall seeing any user
    documentation listing them. Does this mean that gcc+glibc
    is noncompilant in this aspect?

    I think it's reasonable to say that the appearance of a macro
    name being #define'd in a standard header qualifies as
    documenting the name being #define'd.

    I disagree. I don't think it's reasonable to say that.

    Headers are not documentation.

    It makes no sense for a file to be a document, just because it is
    part of the implementation, ipso facto.

    A binary executable contains text written in a machine language that
    we can read and understand---some people without the aid of a
    disassembler, even. It does not therefore follow that a compiler
    executable is documentation.

    No artifact delivered by the implementor is part of the documentation
    unless it is designated as such.

    A header file is documentation if the implementor indicates it as a
    document, otherwise not. And then, it may be that only certain
    designated and delimited parts of the header file are indicated as documentation. For instance, some other document may direct the reader
    to read the block comments in a certain header file. Then only block
    comments are documentation, and not any definitions outside of comments.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Tue Jan 6 21:51:24 2026
    From Newsgroup: comp.lang.c

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    ...

    Note: in C2023, the [predefined macro names] section says: "Any other
    predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no
    longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use
    them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then
    unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    J.5 identifies as extensions only "... predefined macros with names that
    do not begin with an underscore." (J.5, J.5.13)

    That doesn't invalidate what I said. And anyway Annex J is only
    informative, not normative.

    They are not identified as implementation-defined, so there is no
    obligation to document them.

    Let me clarify my earlier comment. An implementation is free to
    accept almost anything at all, as long as a diagnostic is issued.
    But any usage[*] that would otherwise be a syntax error or violate
    a constraint, if accepted without issuing a diagnostic, must be an
    extension and so must be documented.

    [*] an ordinary use, not a declaring or defining use.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Tue Jan 6 21:57:01 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    [...]

    Note: in C2023, the [predefined macro names] section says: "Any other
    predefined macro names: shall begin with a leading underscore
    followed by an uppercase letter; or, a second underscore...". For
    earlier versions of the standard, user code should avoid using such
    identifiers because they were reserved for all purposes, but that's no
    longer the case. Now, they should be avoided because they may be
    pre-defined by the implementation, which means that any attempt to use
    them might have unpredictable results.

    That's right in the sense that if the implementation is unknown then
    unexpected results may occur. However, if the implementation is
    known, then we can find out what results are expected by consulting
    the implementation's documentation for extensions, since any such
    macro name must qualify as an extension, and so much be documented.

    Note by the way that the description in N3220 section 6.10.10.1
    paragraph 2 makes using #define or #undef be undefined behavior only
    for macro names in the subclause (and also a short list of other
    identifiers). Hence any other predefined macro name may be used,
    definedly, simply by using #undef and then #define for the macro
    name in question (in particular, under C23 rules, but not earlier
    versions of the C standard).

    I don't *think* that all implementation-specific predefined macros have
    to be documented -- at least, I'd be surprised if that were the intent.

    For example, I don't think an implementation is required to document its
    use of _STDIO_H (the include guard header in the glibc implementation of <stdio.h>).

    Though it's not normative, N3220 J.5.1 (Common extensions) says:

    Examples of such extensions are new keywords, extra library
    functions declared in standard headers, or predefined macros with
    names that do not begin with an underscore.

    I gave a clarifying response to this question in my recent
    followup to the post from James Kuyper.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Wed Jan 7 03:01:31 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    antispam@fricas.org (Waldek Hebisch) writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    [...]

    Note: in C2023, the [predefined macro names] section says: "Any
    other predefined macro names: shall begin with a leading
    underscore followed by an uppercase letter; or, a second
    underscore...". For earlier versions of the standard, user code
    should avoid using such identifiers because they were reserved
    for all purposes, but that's no longer the case. Now, they
    should be avoided because they may be pre-defined by the
    implementation, which means that any attempt to use them might
    have unpredictable results.

    That's right in the sense that if the implementation is unknown
    then unexpected results may occur. However, if the
    implementation is known, then we can find out what results are
    expected by consulting the implementation's documentation for
    extensions, since any such macro name must qualify as an
    extension, and so much be documented.

    Hmm, looking at '/usr/include/string.h' on my machine I see
    definitions of things like

    __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
    __need_size_t

    and lot of similar things. I do not recall seeing any user
    documentation listing them. Does this mean that gcc+glibc
    is noncompilant in this aspect?

    I think it's reasonable to say that the appearance of a macro
    name being #define'd in a standard header qualifies as
    documenting the name being #define'd.

    I disagree. I don't think it's reasonable to say that.

    Some people think it's reasonable. It's okay if you don't.

    Headers are not documentation. They're often barely human-readable,
    and the system headers aren't necessarily even files.

    Yes, I might have said "standard header file", with the
    understanding that the files in question are encoded in regular
    ascii. There isn't any requirement that the document(s) be easy
    to read.

    As long as the #define is
    readable in an ordinary source file, there isn't any mystery
    about the name being used or what its definition is.

    System headers can be arbitrarily complex, with #includes for other system-specific headers, nests of #ifs and #ifdefs, and so on.

    As long as they define all implementation-defined characteristics
    (and I suppose can be understood by humans), how complex they are
    doesn't matter. That's a QOI issue, not a conformance issue.

    I suppose
    that to satisfy the letter of the C standard, the accompanying
    document would need to incorporate the system header files by
    reference, but surely the header files satisfy the spirit of
    providing the required documentation. Implementation-defined
    values for things like CHAR_BIT and INT_MAX fall under the same
    rule for documentation as do extensions, yet as far as I know
    these values are defined only in system header files, and not in
    any separate document.

    gcc's documentation does have a "C Implementation-Defined Behavior"
    section. It doesn't mention CHAR_BIT by name, but it does document
    "The number of bits in a byte" as "Determined by ABI". I didn't
    find anything similar for INT_MAX.

    I find it implausible that the standard intended to require
    implementations to document all macros defined in standard headers,

    The language in the C standard is clearcut: "An implementation shall
    be accompanied by a document that defines all implementation-defined
    and locale-specified characteristics and all extensions." If gcc
    (together with glibc) doesn't provide such a document, that defines
    ALL implementation-defined characteristics, etc, and system header
    files don't count, then that implementation is not conforming. See
    also my followup to James Kuyper in a closely related sub-thread.
    --- Synchronet 3.21a-Linux NewsLink 1.2