C++ is supposed to be a portable language. It's a lovely phrase, "supposed to be": It explains how we were able to find all the programs for this chapter.
The Rio is an MP3 music player. I worked on some Linux software for this device. Each data block ends with a 16-byte control structure. I carefully laid out the struct statement to make sure that the block structure was correct, yet when I tested the program, my Rio kept losing blocks.
So what is going on?
1 /*************************************************
2 * A small part of a set of routines to *
3 * download music to a RIO mp3 player. *
4 * *
5 * Full sources for the original can be found *
6 * at http://www.oualline.com. *
7 * *
8 * This just tests the writing of the end of *
9 * block structure to the device. *
10 *************************************************/
11
12 #include <stdio.h>
13 /*
14 * The 16 byte end of block structure for a Rio.
15 * (We'd label the fields if we knew what they
16 * were.)
17 */
18 struct end_block_struct
19 {
20 unsigned long int next_512_pos; // [0123]
21 unsigned char next_8k_pos1; // [4]
22 unsigned char next_8k_pos2; // [5]
23
24 unsigned long int prev_251_pos; // [6789]
25 unsigned char prev_8k_pos1; // [10]
26 unsigned char prev_8k_pos2; // [11]
27
28 unsigned short check_sum; // [12,13]
29 unsigned short prev_32K_pos; // [14,15]
30 };
31
32 /*
33 * Macro to print offset of the
34 * field in the structure
35 */
36 #define OFFSET(what) \
37 printf(#what " %d\n", int(&ptr->what));
38
39 int main()
40 {
41 // A structure for debugging the structure
42 struct end_block_struct *ptr = NULL;
43
44 printf("Structure size %d\n",
45 sizeof(end_block_struct));
46 OFFSET(next_512_pos);
47 OFFSET(next_8k_pos1);
48 OFFSET(next_8k_pos2);
49
50 OFFSET(prev_251_pos);
51 OFFSET(prev_8k_pos1);
52 OFFSET(prev_8k_pos2);
53
54 OFFSET(check_sum);
55 OFFSET(prev_32K_pos);
56 return (0);
57 }
(Next Hint 343. Answer 103.)