fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define Stringify_(x_) # x_
  5. #define Stringify(x_) Stringify_(x_)
  6.  
  7. #define test(x_) ( \
  8.   printf("%s: '%s'\n", (x_) ? "True" : "False", Stringify(x_)) \
  9.   )
  10.  
  11. /* Choose your base type, here */
  12. typedef int sometype;
  13.  
  14. /*
  15.  * 'sizeof' is an operator, not a function.
  16.  * The 'sizeof' operator has two forms:
  17.  
  18.   sizeof unary-expression
  19.   sizeof (type-name)
  20.  
  21.  * if you use a 'type-name', it must be enclosed by
  22.  * parentheses. If you use a 'unary-expression',
  23.  * such as a constant value or the value of an object,
  24.  * then the parentheses can be omitted.
  25.  *
  26.  * The 'sizeof' operator will only perform evaluation
  27.  * on its operand if the operand type is a variable
  28.  * length array type: An array whose count of elements
  29.  * is not known when the program is compiled, but only
  30.  * at run-time.
  31.  */
  32.  
  33. int main(void) {
  34. sometype ***** foo;
  35.  
  36. /* See how a '*' on the left corresponds to one less on the right */
  37. test(sizeof foo == sizeof (sometype *****));
  38. test(sizeof *foo == sizeof (sometype ****));
  39. test(sizeof **foo == sizeof (sometype ***));
  40. test(sizeof ***foo == sizeof (sometype **));
  41. test(sizeof ****foo == sizeof (sometype *));
  42. test(sizeof *****foo == sizeof (sometype));
  43.  
  44. /*
  45.   * Suppose that you used the pattern
  46.  
  47.   foo = malloc(sizeof (sometype ****));
  48.  
  49.   * for each of the allocations, below.
  50.   * Then suppose you change your mind and want to
  51.   * use a different type than 'sometype'. You would
  52.   * have to change every line. If you use the
  53.   * pattern below, you only have to change line 34!
  54.   */
  55.  
  56. foo = malloc(sizeof *foo);
  57. if (!foo) return EXIT_FAILURE;
  58.  
  59. *foo = malloc(sizeof **foo);
  60. if (!*foo) return EXIT_FAILURE;
  61.  
  62. **foo = malloc(sizeof ***foo);
  63. if (!**foo) return EXIT_FAILURE;
  64.  
  65. ***foo = malloc(sizeof ****foo);
  66. if (!***foo) return EXIT_FAILURE;
  67.  
  68. ****foo = malloc(sizeof *****foo);
  69. if (!****foo) return EXIT_FAILURE;
  70.  
  71. *****foo = 42;
  72. test(*****foo == 42);
  73.  
  74. free(****foo);
  75. free(***foo);
  76. free(**foo);
  77. free(*foo);
  78. free(foo);
  79.  
  80. return EXIT_SUCCESS;
  81. }
  82.  
Success #stdin #stdout 0.02s 1852KB
stdin
Standard input is empty
stdout
True: 'sizeof foo == sizeof (sometype *****)'
True: 'sizeof *foo == sizeof (sometype ****)'
True: 'sizeof **foo == sizeof (sometype ***)'
True: 'sizeof ***foo == sizeof (sometype **)'
True: 'sizeof ****foo == sizeof (sometype *)'
True: 'sizeof *****foo == sizeof (sometype)'
True: '*****foo == 42'