Programming language
C
C is a standardized, compiled language that exposes memory addresses, data representation, and operation costs through a small language core.
What is C and what does it do?
C is a general-purpose language with a compact set of abstractions over memory, values, control flow, and function calls. A compiler translates C source for a target platform, and a linker combines the resulting objects with the libraries the program needs. Operating systems, embedded software, language runtimes, and native libraries often use C because it can stay close to their binary interfaces.
C can be read as a set of explicit contracts. The language provides control over representation and access, but size, lifetime, and valid ranges remain the programmer's responsibility.
A pointer is not a container
A pointer identifies a location. It does not automatically carry the number of elements that may be read from that location. An address and its valid length should therefore stay together at every function boundary.
#include <stddef.h>
int sum(const int *values, size_t count)
{
int total = 0;
for (size_t i = 0; i < count; ++i) {
total += values[i];
}
return total;
}
The loop is ordinary on purpose. Its bounds, accumulator, and reads are visible, so the caller's responsibility is easy to state: values must refer to at least count readable integers.
Ownership needs a sentence
C does not decide who releases dynamically acquired memory or how long a borrowed pointer remains valid. That rule should be expressible in plain language before the implementation is written.
An ownership rule is complete only when it names who creates a resource, who may borrow it, and who releases it.
Each resource contract should answer:
- Can a null or empty value cross this boundary?
- Does the receiver borrow the resource or take ownership?
- Which function performs the matching cleanup?
- What happens when an operation fails halfway through?
The cost model stays visible
C is useful when representation is part of the problem, but visibility is not the same as automatic speed.
| Decision | What still needs verification |
|---|---|
| Contiguous array | Bounds, alignment, and element count |
| Manual allocation | Failure, ownership, and release path |
| Native call | ABI, data layout, and error convention |
| Bit-level operation | Integer width and defined behavior |
This level of control is justified only when it clarifies a real systems constraint. If a managed runtime can remove those responsibilities without hiding an important requirement, it usually offers the smaller risk surface.