In response to a thread on the TRS-80 Color Computer FB group, I wrote a little program to demonstrate a few of the problems you run into when treating pointers to one integer type as pointers to another.

Formato
C
Post date
2020-11-11 22:44
Publication Period
Unlimited
  1. /* A little program to demonstrate a few of the dangers
  2. ** of aliasing pointers to different types of integers.
  3. **
  4. ** To fully appreciate the effects,
  5. ** compile and run this code on both LSB1st and MSB1st CPUs.
  6. **
  7. ** Written in response to a thread on the TRS-80 Color Computer FB group.
  8. **
  9. ** Joel Rees, Amagasaki, Japan, November 2020.
  10. */
  11. #include <stdlib.h>
  12. #include <limits.h>
  13. #include <stdio.h>
  14. typedef char * byteptr_t;
  15. typedef short * shortptr_t;
  16. typedef long * longptr_t;
  17. int main( int argc, char *argv[] )
  18. {
  19. short int shorttest[ 3 ] = { 0, 0, 0 };
  20. long int longtest[ 3 ] = { 0, 0, 0 };
  21. shortptr_t shortptr;
  22. longptr_t longptr;
  23. printf( "Note that both\n"
  24. "least significant first and most significant first\n"
  25. "give unfortanate results.\n"
  26. "Different, but both unfortunate.\n"
  27. "Now that you know they do, see if you can figure out why.\n\n" );
  28. printf( "Let's start with referring to a long as a short, all target bits clear.\n\n" );
  29. shortptr = (short *) &longtest[ 1 ];
  30. printf( "longtest before: %ld %ld %ld (hex: %lx %lx %lx)\n",
  31. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  32. printf( "Test: ( * shortptr ) = 1 \n" );
  33. ( * shortptr ) = 1;
  34. printf( "longtest after: %ld %ld %ld (hex: %lx %lx %lx)\n",
  35. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  36. printf( "We thought we wrote: %d. We actually wrote %ld between %ld and %ld.\n",
  37. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  38. printf( "In hexadecimal,\n" );
  39. printf( "We thought we wrote: %x. We actually wrote %lx between %lx and %lx.\n",
  40. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  41. printf( "\nAgain, setting all target bits,\n" );
  42. longtest[ 0 ] = longtest[ 1 ] = longtest[ 2 ] = -1;
  43. printf( "longtest before: %ld %ld %ld (hex: %lx %lx %lx)\n",
  44. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  45. printf( "Test: ( * shortptr ) = 1 \n" );
  46. ( * shortptr ) = 1;
  47. printf( "longtest after: %ld %ld %ld (hex: %lx %lx %lx)\n",
  48. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  49. printf( "We thought we wrote: %d. We actually wrote %ld between %ld and %ld.\n",
  50. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  51. printf( "In hexadecimal,\n" );
  52. printf( "We thought we wrote: %x. We actually wrote %lx between %lx and %lx.\n",
  53. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  54. printf( "\n\nClearing all target bits,\n" );
  55. longtest[ 0 ] = longtest[ 1 ] = longtest[ 2 ] = 0;
  56. printf( "longtest before: %ld %ld %ld (hex: %lx %lx %lx)\n",
  57. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  58. printf( "Test: ( * shortptr ) = -1 \n" );
  59. ( * shortptr ) = -1;
  60. printf( "longtest after: %ld %ld %ld (hex: %lx %lx %lx)\n",
  61. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  62. printf( "We thought we wrote: %d. We actually wrote %ld between %ld and %ld.\n",
  63. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  64. printf( "In hexadecimal,\n" );
  65. printf( "We thought we wrote: %x. We actually wrote %lx between %lx and %lx.\n",
  66. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  67. printf( "\nAgain, setting all target bits,\n" );
  68. longtest[ 0 ] = longtest[ 1 ] = longtest[ 2 ] = -1;
  69. printf( "longtest before: %ld %ld %ld (hex: %lx %lx %lx)\n",
  70. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  71. printf( "Test: ( * shortptr ) = -1 \n" );
  72. ( * shortptr ) = -1;
  73. printf( "longtest after: %ld %ld %ld (hex: %lx %lx %lx)\n",
  74. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  75. printf( "We thought we wrote: %d. We actually wrote %ld between %ld and %ld.\n",
  76. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  77. printf( "In hexadecimal,\n" );
  78. printf( "We thought we wrote: %x. We actually wrote %lx between %lx and %lx.\n",
  79. * shortptr, longtest[ 1 ], longtest[ 0 ], longtest[ 2 ] );
  80. printf( "\n\nTime for arithmetic on small integers.\n" );
  81. printf( "Clearing ..." );
  82. longtest[ 0 ] = longtest[ 1 ] = longtest[ 2 ] = 0;
  83. printf( "longtest before: %ld %ld %ld (hex: %lx %lx %lx)\n",
  84. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  85. printf( "Test: ( * shortptr ) -= 1 (subtract 1)\n" );
  86. ( * shortptr ) -= 1;
  87. printf( "* shortptr sees %d (%x)\n", * shortptr, *shortptr );
  88. printf( "longtest after: %ld %ld %ld (hex: %lx %lx %lx)\n",
  89. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  90. printf( "\nClearing ..." );
  91. longtest[ 0 ] = longtest[ 1 ] = longtest[ 2 ] = 0;
  92. printf( "longtest before: %ld %ld %ld (hex: %lx %lx %lx)\n",
  93. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  94. printf( "Test: ( * shortptr ) += 1 (add 1)\n" );
  95. ( * shortptr ) += 1;
  96. printf( "* shortptr sees %d (%x)\n", * shortptr, *shortptr );
  97. printf( "longtest after: %ld %ld %ld (hex: %lx %lx %lx)\n",
  98. longtest[ 0 ], longtest[ 1 ], longtest[ 2 ], longtest[ 0 ], longtest[ 1 ], longtest[ 2 ] );
  99. /********/
  100. printf( "\n\n\nNow let's refer to a short as a long.\n\n" );
  101. longptr = (long *) &shorttest[ 1 ];
  102. printf( "shorttest before: %d %d %d (hex: %x %x %x)\n",
  103. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  104. printf( "Test: ( * longptr ) = 1 \n" );
  105. ( * longptr ) = 1;
  106. printf( "shorttest after: %d %d %d (hex: %x %x %x)\n",
  107. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  108. printf( "We thought we wrote: %ld. We actually wrote %d between %d and %d.\n",
  109. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  110. printf( "In hexadecimal,\n" );
  111. printf( "We thought we wrote: %lx. We actually wrote %x between %x and %x.\n",
  112. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  113. printf( "\nAgain, setting all target bits,\n" );
  114. shorttest[ 0 ] = shorttest[ 1 ] = shorttest[ 2 ] = -1;
  115. printf( "shorttest before: %d %d %d (hex: %x %x %x)\n",
  116. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  117. printf( "Test: ( * longptr ) = 1 \n" );
  118. ( * longptr ) = 1;
  119. printf( "shorttest after: %d %d %d (hex: %x %x %x)\n",
  120. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  121. printf( "We thought we wrote: %ld. We actually wrote %d between %d and %d.\n",
  122. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  123. printf( "In hexadecimal,\n" );
  124. printf( "We thought we wrote: %lx. We actually wrote %x between %x and %x.\n",
  125. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  126. printf( "\n\nClearing all target bits,\n" );
  127. shorttest[ 0 ] = shorttest[ 1 ] = shorttest[ 2 ] = 0;
  128. printf( "shorttest before: %d %d %d (hex: %x %x %x)\n",
  129. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  130. printf( "Test: ( * longptr ) = -1 \n" );
  131. ( * longptr ) = -1;
  132. printf( "shorttest after: %d %d %d (hex: %x %x %x)\n",
  133. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  134. printf( "We thought we wrote: %ld. We actually wrote %d between %d and %d.\n",
  135. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  136. printf( "In hexadecimal,\n" );
  137. printf( "We thought we wrote: %lx. We actually wrote %x between %x and %x.\n",
  138. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  139. printf( "\nAgain, setting all target bits,\n" );
  140. shorttest[ 0 ] = shorttest[ 1 ] = shorttest[ 2 ] = -1;
  141. printf( "shorttest before: %d %d %d (hex: %x %x %x)\n",
  142. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  143. printf( "Test: ( * longptr ) = -1 \n" );
  144. ( * longptr ) = -1;
  145. printf( "shorttest after: %d %d %d (hex: %x %x %x)\n",
  146. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  147. printf( "We thought we wrote: %ld. We actually wrote %d between %d and %d.\n",
  148. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  149. printf( "In hexadecimal,\n" );
  150. printf( "We thought we wrote: %lx. We actually wrote %x between %x and %x.\n",
  151. * longptr, shorttest[ 1 ], shorttest[ 0 ], shorttest[ 2 ] );
  152. printf( "\n\nTime for arithmetic on small integers.\n" );
  153. printf( "Clearing ..." );
  154. shorttest[ 0 ] = shorttest[ 1 ] = shorttest[ 2 ] = 0;
  155. printf( "shorttest before: %d %d %d (hex: %x %x %x)\n",
  156. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  157. printf( "Test: ( * longptr ) -= 1 (subtract 1)\n" );
  158. ( * longptr ) -= 1;
  159. printf( "* longptr sees %d (%x)\n", * shortptr, *shortptr );
  160. printf( "shorttest after: %d %d %d (hex: %x %x %x)\n",
  161. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  162. printf( "\nClearing ..." );
  163. shorttest[ 0 ] = shorttest[ 1 ] = shorttest[ 2 ] = 0;
  164. printf( "shorttest before: %d %d %d (hex: %x %x %x)\n",
  165. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  166. printf( "Test: ( * longptr ) += 1 (add 1)\n" );
  167. ( * longptr ) += 1;
  168. printf( "* longptr sees %d (%x)\n", * shortptr, *shortptr );
  169. printf( "shorttest after: %d %d %d (hex: %x %x %x)\n",
  170. shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ], shorttest[ 0 ], shorttest[ 1 ], shorttest[ 2 ] );
  171. printf( "To get the full effect of this,\n"
  172. "be sure to compile and run on both least significant first\n"
  173. "and most significant first architectures.\n"
  174. "Ask yourself, \n"
  175. "on which architecture will you notice the effects more quickly?\n\n" );
  176. return EXIT_SUCCESS;
  177. }
Download Printable view

URL of this paste

Embed with JavaScript

Embed with iframe

Raw text