Method Man said:
Say I have the following:
int main(void) {
char* p, q;
This is deceptive syntax. It *looks* like it's meant to declare
two pointers, but it *actually* declares a pointer and an
integer.
p = (char*) malloc(sizeof(char)*10);
I don't recommend casting the return value of malloc():
* The cast is not required in ANSI C.
* Casting its return value can mask a failure to #include
<stdlib.h>, which leads to undefined behavior.
* If you cast to the wrong type by accident, odd failures can
result.
Some others do disagree, such as P.J. Plauger (see article
<
[email protected]>).
When calling malloc(), I recommend using the sizeof operator on
the object you are allocating, not on the type. For instance,
*don't* write this:
int *x = malloc (128 * sizeof (int)); /* Don't do this! */
Instead, write it this way:
int *x = malloc (128 * sizeof *x);
There's a few reasons to do it this way:
* If you ever change the type that `x' points to, it's not
necessary to change the malloc() call as well.
This is more of a problem in a large program, but it's still
convenient in a small one.
* Taking the size of an object makes writing the statement
less error-prone. You can verify that the sizeof syntax is
correct without having to look at the declaration.
Finally, sizeof(char) is always 1.
q = (p + 100) - 99; /* legal? */
Constraint violation that requires a diagnostic. See C99
6.5.16.1 "Simple assignment". Also, the pointer arithmetic
yields undefined behavior, because you're going beyond
one-past-the-end in an array.
free(q - 1); /* legal? */
Also a constraint violation. See C99 6.5.2.2 "Function calls"
para 2.
....
return 0;
}
Will this program always produce UB, always work, or is it compiler
dependent?
It won't compile without diagnostics. It also produces undefined
behavior.