address of structure == address of first member? (long)

Carl Paukstis carlp at iscuva.ISCS.COM
Tue Nov 22 05:45:40 AEST 1988


In my H&S, 5.7.3 (p. 108) says "... C compilers are constrained to assign
components increasing memory addresses in a strict left-to-right order,
with the first component starting at the beginning address of the structure
itself."

Fine. I want to write a general-purpose search function.  I have several
arrays of (different) structures; each structure contains a pointer to a char
string identifier as its first member.  The search function takes a
character (string) pointer to a search argument, a pointer to one of the
arrays of structures, the size the structure entry, and the number of
entries in the table.  It finds the table entry containing the (pointer to)
string specified, and returns a pointer to the matching table entry.

By H&S, that part of the code which gets the pointer to the string to do
the compare must work.  And the following compiles and runs clean under
gcc (1.30) under Ultrix and another (semi-)ANSI(draft)compliant compiler
on a SYS V system.  What other portability problems will I run into with
this code?  How can I fix them?

 1	#include <stdio.h>
 2
 3	struct mumble {
 4	    char *dopey;
 5	    float sneezy;
 6	    int doc;
 7	    };
 8
 9	struct fumble {
10	    char *bashful;
11	    char grumpy;
12	    float sleepy;
13	    };
14
15	const struct mumble m[10] = {
16	    { "abc", 1.3, 4 },
17	    { "def", 2.5, 2 },
18	    { "ghi", 2.6, 1 },
19	    { "ghj", 2.67, 0 },
20	    { "zzzkl", 9.4, -2 }
21	    };
22
23	const struct fumble f[12] = {
24	    { "annapolis", 'b', 907.4 },
25	    { "brainerd", 'c', 821.0 },
26	    { "collinston", 'd', 1243.6},
27	    { "detroit", 'e', 3.2 },
28	    { "evanston", 'f', 1.1054 },
29	    { "fargo", 'g', 1204.0 },
30	    { "gonzaga", 'z', 3.1415926 },
31	    { "zulu", 'a', 92203.1 }
32	    };
33
34	main()
35	{
36	    void * mybsearch(const char *, void const *, const int, const int);
37	    struct mumble *pm;
38	    struct fumble *pf;
39
40	    pm = (struct mumble *)mybsearch ("ghj",
41	            (void *)m,
42	            sizeof(m)/sizeof(struct mumble),
43	            sizeof(struct mumble));
44
45	    if (0 == pm)
46	        {
47	        printf("Not found in m!\n");
48	        exit(1);
49	        }
50	    printf("Value for ghj is %f\n",pm->sneezy);
51
52	    pf = (struct fumble *)mybsearch ("evanston",
53	            (void *)f,
54	            sizeof(f)/sizeof(struct fumble),
55	            sizeof(struct fumble));
56
57	    if (0 == pf)
58	        {
59	        printf("Not found in f!\n");
60	        exit(1);
61	        }
62	    printf("Value for evanston is %f\n",pf->sleepy);
63
64	    printf("OK, found both!\n");
65	    exit(0);
66	}
67
68	/**
69	**  simple-minded binary search routine:
70	**      Find a table entry which matches the desired string.
71	**      Table entries are assumed to be structures, the first
72	**      member of which is a pointer to a character string key.
73	**/
74
75	void * mybsearch (const char * key,     /* value to match against */
76	                void const * table,     /* first table entry */
77	                const int count,        /* number of table entries */
78	                const int size)         /* size (char's) of each entry */
79	{
80	    int l, m, r;
81	    int code;
82	    for (l = 0, r = count - 1; l <= r;)
83	    {
84	        m = (l + r) / 2;
85
86	        code = strcmp (key, *(char **)((char *)table + (m * size)));
87
88	        if (code == 0)      /* found it! */
89	            return ((void *)((char *)table + (m * size)));
90
91	        if (code < 0)
92	            r = m - 1;      /* search left half */
93	        else
94	            l = m + 1;      /* search right half */
95	    }
96
97	    return ((void *) 0);    /* not found */
98	}
99

Line 86 bothers me.  Is it permissible to cast a void* into a char* and do
arithmetic on it like this?  Line 89 would have the same problem (if any).

On machines (environments?) with non-byte-sized chars, is there a better
way to do the necessary arithmetic?  Or what else have I missed?

-- 
Carl Paukstis    +1 509 927 5600 x5321  |"I met a girl who sang the blues
                                        | and asked her for some happy news
UUCP:     carlp at iscuvc.ISCS.COM         | but she just smiled and turned away"
          ...uunet!iscuvc!carlp         |                    - Don MacLean



More information about the Comp.lang.c mailing list