Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What can you do in C without "std" includes? Are they part of "C," or just libraries?

Tags:

c

standards

I apologize if this is a subjective or repeated question. It's sort of awkward to search for, so I wasn't sure what terms to include.

What I'd like to know is what the basic foundation tools/functions are in C when you don't include standard libraries like stdio and stdlib.

What could I do if there's no printf(), fopen(), etc?

Also, are those libraries technically part of the "C" language, or are they just very useful and effectively essential libraries?

like image 471
Chris Cooper Avatar asked Apr 03 '10 23:04

Chris Cooper


People also ask

Does C use STD?

All C++ standard library names, including the C library names, if you include them, are defined in the namespace std . This means that you must qualify all the library names using one of the following methods: Specify the standard namespace, for example: std::printf("example\n");

Is Std a library in C++?

The Standard Template Library (STL) is a set of C++ template classes to provide common programming data structures and functions such as lists, stacks, arrays, etc. It is a library of container classes, algorithms, and iterators. It is a generalized library and so, its components are parameterized.

Is there something that I can do in C and not in C++?

There's no computation you can accomplish in one language but not the other. There are programs that will do one thing in C and something else in C++ (or fail to compile) according to the Standard, although rewriting these is usually trivial.

Should you use libraries in coding?

Since you're a junior programmer, I would recommend you not to use any libraries unless you have no interest in the task. Facing the problem would be the best approach for learning. Don't let libraries hide knowledge from you.


2 Answers

What could I do if there's no printf(), fopen(), etc?

As long as you know how to interface the system you are using you can live without the standard C library. In embedded systems where you only have several kilobytes of memory, you probably don't want to use the standard library at all.

Here is a Hello World! example on Linux and Windows without using any standard C functions:

For example on Linux you can invoke the Linux system calls directly in inline assembly:

/* 64 bit linux. */  #define SYSCALL_EXIT 60 #define SYSCALL_WRITE 1  void sys_exit(int error_code) {     asm volatile     (         "syscall"         :          : "a"(SYSCALL_EXIT), "D"(error_code)         : "rcx", "r11", "memory"     ); }  int sys_write(unsigned fd, const char *buf, unsigned count) {     unsigned ret;      asm volatile     (         "syscall"         : "=a"(ret)         : "a"(SYSCALL_WRITE), "D"(fd), "S"(buf), "d"(count)         : "rcx", "r11", "memory"     );          return ret; }  void _start(void) {     const char hwText[] = "Hello world!\n";      sys_write(1, hwText, sizeof(hwText));     sys_exit(12); } 

You can look up the manual page for "syscall" which you can find how can you make system calls. On Intel x86_64 you put the system call id into RAX, and then return value will be stored in RAX. The arguments must be put into RDI, RSI, RDX, R10, R9 and R8 in this order (when the argument is used).

Once you have this you should look up how to write inline assembly in gcc. The syscall instruction changes the RCX, R11 registers and memory so we add this to the clobber list make GCC aware of it.

The default entry point for the GNU linker is _start. Normally the standard library provides it, but without it you need to provide it. It isn't really a function as there is no caller function to return to. So we must make another system call to exit our process.

Compile this with:

gcc -nostdlib nostd.c  

And it outputs Hello world!, and exits.

On Windows the system calls are not published, instead it's hidden behind another layer of abstraction, the kernel32.dll. Which is always loaded when your program starts whether you want it or not. So you can simply include windows.h from the Windows SDK and use the Win32 API as usual:

#include <windows.h>  void _start(void) {     const char str[] = "Hello world!\n";     HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);     DWORD written;      WriteFile(stdout, str, sizeof(str), &written, NULL);     ExitProcess(12); } 

The windows.h has nothing to do with the standard C library, as you should be able to write Windows programs in any other language too.

You can compile it using the MinGW tools like this:

gcc -nostdlib C:\Windows\System32\kernel32.dll nostdlib.c 

Then the compiler is smart enough to resolve the import dependencies and compile your program.

If you disassemble the program, you can see only your code is there, there is no standard library bloat in it.

So you can use C without the standard library.

like image 45
Calmarius Avatar answered Oct 22 '22 15:10

Calmarius


The C standard has this to say (5.1.2.3/5):

The least requirements on a conforming implementation are:

— At sequence points, volatile objects are stable in the sense that previous accesses are complete and subsequent accesses have not yet occurred.

— At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.

— The input and output dynamics of interactive devices shall take place as specified in 7.19.3.

So, without the standard library functions, the only behavior that a program is guaranteed to have, relates to the values of volatile objects, because you can't use any of the guaranteed file access or "interactive devices". "Pure C" only provides interaction via standard library functions.

Pure C isn't the whole story, though, since your hardware could have certain addresses which do certain things when read or written (whether that be a SATA or PCI bus, raw video memory, a serial port, something to go beep, or a flashing LED). So, knowing something about your hardware, you can do a whole lot writing in C without using standard library functions. Potentially, you could implement the C standard library, although this might require access to special CPU instructions as well as special memory addresses.

But in pure C, with no extensions, and the standard library functions removed, you basically can't do anything other than read the command line arguments, do some work, and return a status code from main. That's not to be sniffed at, it's still Turing complete subject to resource limits, although your only resource is automatic and static variables, no heap allocation. It's not a very rich programming environment.

The standard libraries are part of the C language specification, but in any language there does tend to be a line drawn between the language "as such", and the libraries. It's a conceptual difference, but ultimately not a very important one in principle, because the standard says they come together. Anyone doing something non-standard could just as easily remove language features as libraries. Either way, the result is not a conforming implementation of C.

Note that a "freestanding" implementation of C only has to implement a subset of standard includes not including any of the I/O, so you're in the position I described above, of relying on hardware-specific extensions to get anything interesting done. If you want to draw a distinction between the "core language" and "the libraries" based on the standard, then that might be a good place to draw the line.

like image 130
Steve Jessop Avatar answered Oct 22 '22 15:10

Steve Jessop