From C
#include <stdio.h>
#include <stdlib.h>
#define Stringify_(x_) # x_
#define Stringify(x_) Stringify_(x_)
#define test(x_) ( \
printf("%s: '%s'\n", (x_) ? "True" : "False", Stringify(x_)) \
)
/* Choose your base type, here */
typedef int sometype;
/*
* 'sizeof' is an operator, not a function.
* The 'sizeof' operator has two forms:
sizeof unary-expression
sizeof (type-name)
* if you use a 'type-name', it must be enclosed by
* parentheses. If you use a 'unary-expression',
* such as a constant value or the value of an object,
* then the parentheses can be omitted.
*
* The 'sizeof' operator will only perform evaluation
* on its operand if the operand type is a variable
* length array type: An array whose count of elements
* is not known when the program is compiled, but only
* at run-time.
*/
int main(void) {
sometype ***** foo;
/* See how a '*' on the left corresponds to one less on the right */
test(sizeof foo == sizeof (sometype *****));
test(sizeof *foo == sizeof (sometype ****));
test(sizeof **foo == sizeof (sometype ***));
test(sizeof ***foo == sizeof (sometype **));
test(sizeof ****foo == sizeof (sometype *));
test(sizeof *****foo == sizeof (sometype));
/*
* Suppose that you used the pattern
foo = malloc(sizeof (sometype ****));
* for each of the allocations, below.
* Then suppose you change your mind and want to
* use a different type than 'sometype'. You would
* have to change every line. If you use the
* pattern below, you only have to change line 34!
*/
foo = malloc(sizeof *foo);
if (!foo) return EXIT_FAILURE;
*foo = malloc(sizeof **foo);
if (!*foo) return EXIT_FAILURE;
**foo = malloc(sizeof ***foo);
if (!**foo) return EXIT_FAILURE;
***foo = malloc(sizeof ****foo);
if (!***foo) return EXIT_FAILURE;
****foo = malloc(sizeof *****foo);
if (!****foo) return EXIT_FAILURE;
*****foo = 42;
test(*****foo == 42);
free(****foo);
free(***foo);
free(**foo);
free(*foo);
free(foo);
return EXIT_SUCCESS;
}