Pointers
Pointer arithmetic on void *
is not allowed since the size of pointed-to data is unknown.
"dangling pointer" == points to a deleted object
"wild pointer" == points to uninitialized uninitialized pointer
Converting from an array to a pointer loses size information
char str[256];
printf ("%zu\n", sizeof str); // 256
char *pstr = str;
printf ("%zu\n", sizeof pstr); // 4 or 8 (size of pointer).
Memory management
"static" == allocated at compile time
"automatic" == allocated on the stack
"dynamic" == allocated on the heap
Types of behavior
"implementation-defined" == implementation must document. E.g. propagation of sign bit on >>
operation.
"undefined behavior" == no requirements. E.g. signed overflow.
"unspecified behavior" == two or more possible behaviors E.g. order of argument evaluation.
"locale-specific behavior" == depends on local conventions. E.g. whether tolower returns true for characters other than 26 lowercase Latin letters.
The number of bits in a byte is implementation defined.
An assignment is an expression evaluating to the left-hand side. E.g. (c = getchar())
evaluates to c
.
extern
can be used inside a function definition. E.g.
int x;
void foo() {
extern int x;
}
External and static variables are initialized to 0.
String literals cannot be modified. E.g.
char *s = "abc";
s[0] = `d`; // not allowed
C89 int division with negative numbers is implementation defined. 7 / -2
can be -3
or -4
(round up or down). C99 defines as -3
(toss the decimal after division).
If fn
is called but not declared, the compiler assumes it is defined as int fn()
.
Arithmetic and comparison of pointers that do not point to the same array is undefined behavior (exception is one past the last element in the array).
You may omit the first dimension of a multi-dimensional array in parameters. E.g. void f(int arr[][13])
argv[argc]
is NULL
.
sizeof
does not require parenthesis for objects. sizeof object
vs. sizeof (type name)
.
C supports bit fields. The order of bits is implementation defined. E.g.
struct {
unsigned int is_keyword : 1;
unsigned int is_extern : 1;
unsigned int is_static : 1;
}
printf format is %[-][<width>][.][<precision>][h|l][<conversion>]
. <width>
or <precision>
may be *
.
FILE*
is OS independent. File descriptors are Unix specific.
Top comments (2)
A "wild pointer" doesn't necessarily point to uninitialized memory. It's the pointer itself that is uninitialized. As a consequence, it can point to any address in memory. There's a chance it can just so happen to point to an arbitrary address already within your program such as the text segment of even in your current stack frame. Therefore, it could just so happen to point to memory that has already been initialized. If it's not a
char*
, then it's also likely unaligned. For example, it could point to the second byte of an already initialized 4-byte integer; or it could just by luck be aligned and your program might even appear to work.@pauljlucas good catch. It was incorrectly transcribed from my written notes. The post has been updated.