rr@csuna.cs.uh.edu (Ravi Ramachandran) (03/17/90)
First, apologies if this subject has been thrashed to death before. Now, let the mystery story unfold. I remember that when I first tried fooling around with semaphores, I had a little trouble. Then I pulled out the stuff from a nice book: "UNIX System V Prog. Guide" (AT&T) - Prentice hall. A pal of mine was trying to use semaphores on a Sys V Rel 3 system, yesterday, and was having trouble with the semop() command. To quote from the manual, int semop(semid, sops, nsops) int semid; struct sembuf **sops; int nsops; while my program had, struct sembuf sops[10]; rtrn = semop(semid, sops, nsops); Throw your concentration on the second field. As you can see, they are different. (Modified his program & it worked.) However, we couldn't believe that the manual could be wrong. Decided to refer to the books by the gurus. Looked up "Adv. Unix Prog." (Marc J. Rochkind) - Prentice Hall. On pg 188, he says (prob. from the manual): int semop(sid, ops, nops) int sid; struct sembuf (*ops)[]; int nops; However, the program on pg. 190 goes: struct sembuf sb; semop(semid, &sb, 1); Finally, checked up "The Design of the UNIX operating system" (Maurice J. Bach) - Prentice-Hall. On pg. 373 he says, "...oplist is a pointer to an array of semaphore operations ..." (It should be " oplist is an array of ..." ?) The prog. in Fig 11.14 gives: struct sembuf psembuf, vsembuf; semop(semid, &psembuf, 1); semop(semid, &vsembuf, 1); As a last measure, ran my version of semaphores on a Tolerant, Pyramid, and an OST. Works. Checked the man pages on all these systems. They are the ones with the double pointer. So, what's the deal? I know there must be zillions of people who have noticed this before. The butler did it, --ravi- PS: Just check the SUN man pages; seems to be the right way: int semop(semid, sops, nsops) int semid; struct sembuf *sops; int nsops; PPS: The only reason that I've mentioned a couple of books here is b'cos those books have been my UNIX bibles.
gwyn@smoke.BRL.MIL (Doug Gwyn) (03/18/90)
In article <24407@uhnix1.uh.edu> rr@cs.uh.edu (Ravi Ramachandran) writes: >On pg. 373 he says, "...oplist is a pointer to an array of semaphore >operations ..." >(It should be " oplist is an array of ..." ?) I think this confusion occurred because of the way that C arrays have traditionally been botched. The correct type for the second argument to semop() is (struct sembuf *), and it is expected to point to THE FIRST ELEMENT OF a user-defined array of semaphore operation structures. Because of the C array botch, most documentation (e.g. SVID3) has been calling this a "pointer to a user-defined array of ...". In pre-ANSI C implementations, it was not usually possible to construct a pointer to an array; an attempt to do so would be coerced by the compiler into a pointer to the array's first element. In ANSI C the distinction is important, and the words "the first element of" should be added to the documentation. Note that your suggested fix is wrong; a function parameter cannot have array type in either old or new C.
decot@hpisod2.HP.COM (Dave Decot) (03/19/90)
> A pal of mine was trying to use semaphores on a Sys V Rel 3 system, > yesterday, and was having trouble with the semop() command. > > To quote from the manual, > int semop(semid, sops, nsops) > int semid; > struct sembuf **sops; > int nsops; The above is incorrect, and probably based on a misunderstanding of some bad documentation (probably the bad documentation is on the same page). > while my program had, > > struct sembuf sops[10]; > rtrn = semop(semid, sops, nsops); The above is completely correct. > Looked up "Adv. Unix Prog." (Marc J. Rochkind) - Prentice Hall. > > On pg 188, he says (prob. from the manual): > int semop(sid, ops, nops) > int sid; > struct sembuf (*ops)[]; > int nops; The above is wrong, and is probably based on a misunderstanding of the misused phrase "a pointer to an array" (see below). > However, the program on pg. 190 goes: > struct sembuf sb; > semop(semid, &sb, 1); The above works, because you are using an "array" of size 1, and the "name" of your "array" is &sb. This would also work: struct sembuf sb[1]; semop(semid, sb, 1); > > Finally, checked up "The Design of the UNIX operating system" (Maurice > J. Bach) - Prentice-Hall. > On pg. 373 he says, "...oplist is a pointer to an array of semaphore > operations ..." > (It should be " oplist is an array of ..." ?) No, it *should* be "oplist is a pointer to the first element of an array of semaphore operations" if oplist is the name of the second argument to semop(). Remember that it's impossible to pass arrays to functions. The phrase "pointer to an array of" is often misused when "pointer to the first element of an array of" is meant, even in classic holy scriptures. The reason "everyone understands it" is because types of the form "pointer to an array of" are much less often used. Here's a "pointer to an array of 10 characters": int (*p)[10]; As a parameter declaration, here's a "pointer to the first element of an array of 10 characters": int p[10]; However, most compilers ignore the 10 since it is irrelevant. In fact, I'm not even sure sizeof(p) even cares about the 10. > The prog. in Fig 11.14 gives: > struct sembuf psembuf, vsembuf; > semop(semid, &psembuf, 1); > semop(semid, &vsembuf, 1); These are correct, because you are using semaphore sets of size 1. A pointer to a variable of a certain type works just as fine as a pointer to the first element of an array containing one element of that type. > PS: Just check the SUN man pages; seems to be the right way: > int semop(semid, sops, nsops) > int semid; > struct sembuf *sops; > int nsops; That is a correct declaration. HP-UX has it correct as well. Dave Decot