6 private links
The objective of this proposal is to standardize the usage of common data structures within the context of the C language. The existence of a common standard interface for lists, hash tables, flexible arrays, and other containers has several advantages:
User code remains portable across different projects. In C, we all use the FILE abstraction, for instance. This abstraction allows software to be compatible across a large spectrum of machines and operating systems. Imagine what would happen if each project had to develop a file stream abstraction again and again. This is the case when using lists, for instance. Today, we have in all significant projects written in C a list module, and probably other ones like hash tables, etc.
Avoid duplication of effort. Most of the list or hash tables modules can't be debugged completely and are the source of never ending problems.
Lack of standards makes the merging of two projects very difficult since in most cases the interfaces and data structures are slightly different. This leads to a complete rewrite of one of the modules, or to ädapter" software that will translate from one list implementation to the other, adding yet another layer of complexity to the merged project.
The language becomes more expressive since it becomes possible to reason within a high level environment. The lack of operations for handling advanced data structures conditions programmers to use low level solutions like making an array with a fixed maximum size instead of a list even if the programmer would agree that a list would be a more adequate solution to the problem. Confronted to the alternative of developing yet another list module or opting for a low level solution many time constrained programmers will opt for the second solution.
The portable specifications provide a common framework for library writers and compiler/system designers to build compatible yet strongly specialized implementations.
The language becomes easier to analyze mathematically. In their very interesting paper "Precise reasoning for programs using containers", Dillig, Dillig and Aiken 1 enumerate three main points that make program analysis easier using containers:
Understanding the contents of a container doesn't require understanding the container's implementation
Verifying container implementations requires different techniques and degrees of automation than verifying their clients. Hence, separating these two tasks allows us to choose the verification techniques best suited for each purpose.
There are orders of magnitude more clients of a container than there are container implementations. This fact makes it possible to annotate a handful of library interfaces in order to analyze many programs using these containers.
It is possible to abstract from the nature of any container (using the iterator construct) what allows a series of algorithms to be written without having to bind them to a precise data structure. Containers present a uniform interface to the rest of the program.
LambdaPP is a preprocessor for giving you anonymous functions in C.
If you look at /usr/lib/libc.so; the "library" that gets linked when you specify -lc, it is not a library as such, but a link script which specifies the libraries to link, which also includes the dynamic linker itself:
The course was aimed at C developers who wanted an introduction to both general UNIX-style user-space and Linux kernel development with a focus on embedded systems issues. The course is aimed at two 8-hour days, and is pretty packed in even then.
ELF has two related concepts for managing symbols in your programs. The first concept is the symbol binding. Global binding means the symbol is visible outside the file being built; local binding is the opposite and keeps the symbol local only (static) and weak is like global, but suggests that the symbol can be overridden.
To combat this, ELF provides for visibility attributes. Symbols can be default, protected, hidden or internal. Using these attributes, we can flag extra information for the dynamic loader so it can know which symbols are for public consumption, and which are for internal use only.
The most logical way to use this is to make all symbols by default hidden with -fvisibility=hidden and then "punch holes in the wall" for those symbols you want visible.
This document looks at the numerous and interesting ways the Linux kernel 2.6 interacts with user space programs. We explain sockets, procfs (and similar virtual filesystems), creating new Linux system calls, as well as mundane file and memory handling.
More on userspace interfaces: http://www.ibm.com/developerworks/library/l-kernel-memory-access/
One of the best (but little known) features of GNU C is the attribute mechanism, which allows a developer to attach characteristics to function declarations to allow the compiler to perform more error checking. It was designed in a way to be compatible with non-GNU implementations, and we've been using this for years in highly portable code with very good results.
How to use lib lua
On i386, because of the dearth of general-purpose registers, the calling convention passes all arguments on the stack. This makes the vaarg implementation easy – A valistis simply a pointer into the stack, andvaargjust adds the size of the type to be retrieved to thevalist, and returns the old value. In fact, the i386 ABI reference simply specifiesva_arg
in terms of a single line of code:
On amd64, the problem is much more complicated. To start, amd64 specifies that up to 6 integer arguments and up to 8 floating-point arguments are passed to functions in registers, to take advantage of amd64's larger number of registers. So, for a start, va_arg will have to deal with the fact that some arguments may have been passed in registers, and some on the stack.