Why isn't the C standard library built into the language? - c

I am currently learning C. I understand that many common functions, like printf and scanf are not actually part of the C language -- they are part of the "standard library" of functions.
My question is, why aren't such functions built into the language? Is it a philosophical/design consideration? A matter of efficiency when compiling programs? A necessity in order to act as a "middle layer" to ensure compatibility with different operating systems? Something else entirely?

They are part of C. A C implementation consists of a compiler and a library (and other components, like a linker).
The C core language includes facilities that make it possible to write library code that can be used by other programs. The standard library portion of the standard specifies a library that can be implemented using the facilities defined in the core language.
Some languages do have things like a print command built into the language. C's facilities for writing and invoking library code written in C are powerful enough that that's not necessary.
Furthermore, most of the library is optional for "freestanding" implementations (mostly for embedded systems). There are implementations that support the full core language but that don't provide most of the C standard library.
And a compiler and library can be provided separately. For example, gcc is a compiler; it's commonly used with different library implementations on different systems (GNU libc on Linux, "newlib" on Cygwin, the Microsoft library on Windows with MinGW, and so forth). Mixing and matching like that would be much more difficult if the library were integrated into the core language.
The C language standard (the link is to the newest freely available draft) defines C. Section 6 defines the core language; section 7 defines the standard library.

The thing is that standard allows two kinds of conforming implementation: hosted and freestading, see N1570 4/p6:
The two forms of conforming implementation are hosted and
freestanding. A conforming hosted implementation shall accept any
strictly conforming program. A conforming freestanding implementation
shall accept any strictly conforming program that does not use complex
types and in which the use of the features specified in the library
clause (clause 7) is confined to the contents of the standard headers
<float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>,
<stddef.h>, <stdint.h>, and <stdnoreturn.h>. A conforming implementation may have
extensions (including additional library functions), provided they do
not alter the behavior of any strictly conforming program.
By such design, where the libraries are organized as standard headers it's convienent to simply "cut-off" some header if it is not supported.
Note that C standard defines all headers along with function for standard C library. It's included in C standard indeed, not separate thing somewhere else.

They're part of the language, they're just not part of the grammar.
Factoring I/O out into a separate function library buys you the following:
The grammar becomes easier to parse;
You can target a wider range of platforms; any I/O foibles are handled by the library functions, not by hacking the code generator;
You can implement only as much as is needed to support the platform (i.e., an embedded controller probably doesn't need to read or write formatted output);

Related

Does POSIX-standard require it's specifications to be implemented in the C language only?

Based on the articles I've read on wikipedia and other sources, I've learnt that operating systems like the ones based on UNIX implement the POSIX-API in C. Moreover, I'm yet to find a POSIX-compliant operating system that implements the POSIX-functionalities in any language other than C.
So, does the POSIX-standard require it's specifications to be implemented in the C language only? Can someone implement the POSIX-functionalities for their own(self-made) operating systems in any other programming language like (pure)Rust and get that operating system certified as a POSIX-compliant OS?
It is highly unlikely anybody will ever use header definitions other than for C/C++ again, which are necessary to comply with the standard.
So while technically not necessary, it is practically a necessity or you need to simulate C header behavior from another language + c99 by ISO specification.
"The C-language Development utility c99 shall be supported." (ISO C standard)
https://pubs.opengroup.org/onlinepubs/9699919799/
It is however possible and often practical to conform to the POSIX System Interfaces(what people usual refer to as POSIX-API) and parts of "Shell and Utilities".
To that regard POSIX is "flawed", because it has a "language-lockin".

Why do Windows and Linux have different strdup implementations: strdup() and _strdup()?

When working with strdup on Windows I found out that _strdup is Windows specific, but when I ran the same code on Linux it required strdup without the underscore. Does anyone know the history behind this difference, as-well as some information on how you have dealt with this problem when writing cross-platform code?
There are several functions that are part of the POSIX specification, i.e. Linux and most other UNIX variants, that are not part of standard C. These include strdup, write, read, and others.
The reasoning for the leading underscore is as follows, taken from the MSDN docs:
The Universal C Run-Time Library (UCRT) supports most of the C
standard library required for C++ conformance. It implements the C99
(ISO/IEC 9899:1999) library, with certain exceptions: The type-generic
macros defined in , and strict type compatibility in
. The UCRT also implements a large subset of the POSIX.1
(ISO/IEC 9945-1:1996, the POSIX System Application Program Interface)
C library. However, it's not fully conformant to any specific POSIX
standard. The UCRT also implements several Microsoft-specific
functions and macros that aren't part of a standard.
Functions specific to the Microsoft implementation of Visual C++ are
found in the vcruntime library. Many of these functions are for
internal use and can't be called by user code. Some are documented for
use in debugging and implementation compatibility.
The C++ standard reserves names that begin with an underscore in the
global namespace to the implementation. Both the POSIX functions and
Microsoft-specific runtime library functions are in the global
namespace, but aren't part of the standard C runtime library. That's
why the preferred Microsoft implementations of these functions have a
leading underscore. For portability, the UCRT also supports the
default names, but the Microsoft C++ compiler issues a deprecation
warning when code that uses them is compiled. Only the default names
are deprecated, not the functions themselves. To suppress the warning,
define _CRT_NONSTDC_NO_WARNINGS before including any headers in code
that uses the original POSIX names.
I've handled that by having a #define that check if the program is being compiled for Windows, and if so create another #define to map the POSIX name to the Windows specific name. There are a few choices you can check, although probably the most reliable is _MSC_VER which is defined if MSVC is the compiler.
#ifdef _MSC_VER
#define strdup(p) _strdup(p)
#endif

Procedure to include own functions to ANSI C Standard library

How one can include his/her own programming functions to standard C (ANSI C) library? And any one who is learning or working on C language able to use those functions anywhere anytime, no need of development in general.
Example : someone developed function named "FunFun()" and assume it does fantastic work for most programmers. so how anyone can access this "FunFun" function without developing and just including standard library?
The sane way to approach it would be to develop a 3rd party library and make it available over the internet through open source, Github etc.
The GNU C dialect is one such example, which is a collection of non-standard compiler extensions used by the GCC compiler. One could join the GCC open source group and try to get the new function added there. It would still not be standard library C, but the GCC extensions are often an inspiration to the C standard and several of them (designated initializers, flexible array members, anonymous struct/union etc) have been adopted into the language itself with the C99 and C11 standards. One of the purposes for GNU C is actually to serve as an experimental playground where new languages features can be tried out live.
If you truly wish to add a new function to the actual C standard library, you would have to join the ISO working group and convince them that the function should be added to the language. Or alternatively find a member of the committee and convince them to speak in favour of the new function.
All this of course assuming you are a C programming veteran, or otherwise nobody will likely take you seriously.
Your question can't be answered because it's based on several wrong assumptions.
Things like stdlib.h are not libraries. They are header files intended to be included in your program. Including means the contents are literally pasted into your program at the point of inclusion before the actual compilation happens. They are typically used for declaring functions, types, global variables etc a library provides. The actual library is then linked against after compilation.
There's no such thing as the C library as well as there's no such thing as the C compiler. c is a language that is specified in an open standard (if you're interested, here's the last draft of the latest standard version C11). There are many actual implementations and a complete implementation consists of at least a compiler and a standard library. You can of course implement your own standard library. It's a lot of work to have it really conform to the standard (you would have to implement printf() and scanf() correctly, for example). With your own standard library, you can also include your own extensions, but this would only mean people using your standard library (instead of e.g. glibc on a GNU system) could directly use them.
For having a function available on any implementation of C, it would be necessary to have the C Standard specify it. You won't get a new function in the standard without some very good reasoning.
So if you want to make your own function available to others, do what everyone does and just implement it in your own library. Users can download it, include its headers and link against it.

The ISO C standard defines two classes of conforming implementation

I read this official manual about GCC. Sometimes I have a a problem with translating of text. On the page number six (chapter 2.1) I can't understand such fragment of text:
The ISO C standard defines (in clause 4) two classes of conforming
implementation. A conforming hosted implementation supports the whole
standard including all the library facilities; a conforming
freestanding implementation is only required to provide certain
library facilities: those in <float.h>, <limits.h>, <stdarg.h>, and
<stddef.h>; since AMD1, also those in <iso646.h>; since C99, also
those in <stdbool.h> and <stdint.h>; and since C11, also those in
<stdalign.h> and . In addition, complex types, added in
C99, are not required for freestanding implementations. The standard
also defines two environments for programs, a freestanding
environment, required of all implementations and which may not have
library facilities beyond those required of freestanding
implementations, where the handling of program startup and termination
are implementation-defined, and a hosted environment, which is not
required, in which all the library facilities are provided and startup
is through a function int main (void) or int main (int, char *[]). An
OS kernel would be a freestanding environment; a program using the
facilities of an operating system would normally be in a hosted
implementation.
I am not sure I understand it right...
I will rephrase how I understood it:
Exists two implementations of ISO C standard: a full (named as conforming hosted implementation), and a light (named as conforming freestanding implementation).
Exists two environments (for each of standard's implementation): a hosted environment (for full standard), and a freestanding environment (for light standard).
The light versions is for OS developing. The full versions is for programs, which will work in OS.
And I not understood the phrase about the main function.
I ask to explain me this fragment of text.
It's a bit of both.
The standard defines two runtime environments. One has all of the language, plus a tiny subset of the standard runtime library, plus additional implementation-defined stuff. That's a freestanding environment, and is (as you guessed) intended for programming on the bare metal, e.g. an OS kernel.
The other, more sophisticated environment includes all of the facilities of the above plus all of the standard runtime library. That's a hosted environment, which is intended for application programming.
Now, an implementation is only required to include the facilities of the freestanding environment. If that's all it has, it's called a freestanding implementation. Cross-compilers for deeply embedded microcontrollers are often freestanding implementations, because much of the standard C runtime doesn't make sense or is too big to fit.
Implementing the hosted environment is optional; if an implementation provides the hosted environment it's called a hosted implementation. A hosted implementation must also provide the freestanding environment, i.e. a compilation mode in which only the facilities of a freestanding implementation are available. (This mode would typically be used for compiling things like the C runtime itself, most of which is just more C.)
Finally, the standard signatures for main (int main(void) and int main(int, char **)) are part of the hosted environment. A freestanding environment can use those signatures as well, but it can also define the signature of main to be whatever it likes (void main(void) is common) or use a different name for the entry point.
C11 4/6:
The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>.
First note that "implementation", in the context of the C standard, means "the implementation of a C compiler" and nothing else.
As you correctly state in your question, the freestanding implementation is a compiler for a system that isn't intended to have an operative system beneath it. In other words a freestanding implementation compiler produces programs that are either embedded applications running on a "bare bone" CPU, or programs that are operative systems in themselves. While a hosted implementation is a compiler intended for applications running on top of a OS.
The compiler for freestanding applications only needs to provide the above mentioned headers. The rest of the headers (such as stdio.h) are defined in the mentioned "clause 7" of the standard, but they are not mandatory for a freestanding implementation.
Note however that several libraries are not mandatory to neither hosted nor freestanding implementations, for example the complex number library:
C11 7.3.1:
"Implementations that define the macro _ _STDC_NO_COMPLEX_ _ need not
provide this header nor support any of its facilities."
Furthermore, the two different execution environments, freestanding and hosted, allow different syntax for main(), more info can be found here. A very common misunderstanding among programmers is that the only allowed form in C is int main(), which is only true in a hosted environment.
For example, a freestanding program could start at an out-of-reset interrupt service routine. From there it can call a void main() function, or it could call some other function entirely: it is implementation-defined.
What it means is that a freestanding environment is not required to execute your main() function upon startup. For example, it might be looking for _main() instead (the exact name and signature is implementation defined).

Is the term "libc" equivalent to "C standard library"?

I sometimes hear people using the terms "libc" and "C standard library" interchangeably. I understand that "libc" is the name (or part of the names) of many popular C standard library implementations. My guess is that because of the widespread use of these implementations, people started referring to the C standard library in general as "libc" although it is not an official name.
Is it correct to refer to the C standard library as "libc"?
I always thought that "libc" just happens to be the name (or part of the names) of many popular C standard library implementations.
This is correct. "libc" is the name of some implementations of the C Standard Library.
As an example of a C Standard Library implementation that is not named "libc," the Microsoft C Standard Library implementation is a part of the "C Run-Time Libraries," usually referred to as the "CRT."
Is it correct to refer to the C standard library as "libc"?
The C Standard Library is not named "libc," so using that term to refer to it generically (and not to a particular implementation) would be incorrect. That said, in most contexts, if you did use the term "libc" to refer to the C Standard Library, you are still likely to be understood.
"libc" is indeed the name of the implementation. It often includes functions that are not part of the C standard, and might not include functions that are part of the C standard. (A common case of the latter is the Standard C math functions being split into a separate "libm".)
'libc' refers to the C standard library. However, the libc has several implementations :
glibc : an implementation of libc written for the GNU Project
klibc : a minimalistic subset implementation of the libc
...
LibC (http://www.gnu.org/s/libc/) is one particular implementation of the C library standard (http://en.wikipedia.org/wiki/C_standard_library#ISO_Standard).

Resources