Changeset View
Standalone View
lib/libc/stdlib/bsearch.3
Show First 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
.Bd -literal | .Bd -literal | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
struct person { | struct person { | ||||
char name[5]; | const char *name; | ||||
int age; | int age; | ||||
}; | }; | ||||
int | int | ||||
compare(const void *key, const void *array_member) | compare(const void *a, const void *b) | ||||
{ | { | ||||
int age = (intptr_t) key; | const int *age; | ||||
struct person person = *(struct person *) array_member; | const struct person *person; | ||||
kib: Style(9) disallows initialization in declaration for locals. You cannot avoid it for const… | |||||
Done Inline ActionsI somehow missed it previous time. Why do you copy key/element into local variables ? ` const int *age; const struct person *person; age = a; person = b; return (*age - person->age); kib: I somehow missed it previous time. Why do you copy key/element into local variables ? ```… | |||||
Done Inline ActionsRegarding this copy into local variables and also their initialization, is the qsort(3) EXAMPLE in -current following style(9)? Thanks for your time reviewing this! fernape: Regarding this copy into local variables and also their initialization, is the qsort(3) EXAMPLE… | |||||
Not Done Inline ActionsFirst, it i not a style(9) issue, but just a question of reasonable code. Second, for int's used in the qsort(3) example, it really does not matter do you dereference the values manually as done in the example, or use *a *b an comparision and leave tracking of the values to compiler. But there, I do not see a point to read the name pointer which is implied by assigning the whole structure to the local instance. Even if clever optimizing compiler notes that it can only copy single member, it still has cognitive load on the meat-and-fat reader. kib: First, it i not a style(9) issue, but just a question of reasonable code. Second, for int's… | |||||
Done Inline ActionsUnderstood. Thanks! fernape: Understood.
Thanks! | |||||
return (age - person.age); | age = a; | ||||
person = b; | |||||
return (*age - person->age); | |||||
} | } | ||||
int | int | ||||
main() | main(void) | ||||
{ | { | ||||
struct person *friend; | struct person *friend; | ||||
int age; | |||||
Done Inline ActionsBlanks lines are excessive. kib: Blanks lines are excessive. | |||||
Done Inline ActionsAdd declaration int age; right after this line. kib: Add declaration
```int age;```
right after this line. | |||||
/* Sorted array */ | /* Sorted array */ | ||||
struct person friends[6] = { | const struct person friends[] = { | ||||
{ "paul", 22 }, | { "paul", 22 }, | ||||
{ "anne", 25 }, | { "anne", 25 }, | ||||
{ "fred", 25 }, | { "fred", 25 }, | ||||
{ "mary", 27 }, | { "mary", 27 }, | ||||
{ "mark", 35 }, | { "mark", 35 }, | ||||
{ "bill", 50 } | { "bill", 50 } | ||||
}; | }; | ||||
const size_t len = sizeof(friends) / sizeof(friends[0]); | |||||
Done Inline ActionsNo need for the blank line. kib: No need for the blank line. | |||||
size_t array_size = sizeof(friends) / sizeof(struct person); | age = 22; | ||||
friend = bsearch(&age, friends, len, sizeof(friends[0]), compare); | |||||
Done Inline ActionsI do not believe that the standard in any way specifies that the key (AKA first) argument to bsearch() and compare() must point to an object of the same type as the array element. It should be a valid pointer to some object, and it is up to compare() to make proper use of it. Let it put another way, you can just pass a pointer to int, and dereference int instead of struct person, for the first argument of compare. Then you do not need to create fake name for the search key element. kib: I do not believe that the standard in any way specifies that the key (AKA first) argument to… | |||||
Done Inline ActionsLeave this line as pure asignment, age = 22; kib: Leave this line as pure asignment,
```age = 22;``` | |||||
friend = bsearch((void *)22, &friends, array_size, sizeof(struct person), compare); | |||||
assert(strcmp(friend->name, "paul") == 0); | assert(strcmp(friend->name, "paul") == 0); | ||||
printf("name: %s\enage: %d\en", friend->name, friend->age); | printf("name: %s\enage: %d\en", friend->name, friend->age); | ||||
friend = bsearch((void *)25, &friends, array_size, sizeof(struct person), compare); | age = 25; | ||||
friend = bsearch(&age, friends, len, sizeof(friends[0]), compare); | |||||
Done Inline ActionsMulti-line comment should have a blank line before it. kib: Multi-line comment should have a blank line before it. | |||||
/* | |||||
* For multiple elements with the same key, it is implementation | |||||
* defined which will be returned | |||||
*/ | |||||
assert(strcmp(friend->name, "fred") == 0 || strcmp(friend->name, "anne") == 0); | assert(strcmp(friend->name, "fred") == 0 || strcmp(friend->name, "anne") == 0); | ||||
printf("name: %s\enage: %d\en", friend->name, friend->age); | printf("name: %s\enage: %d\en", friend->name, friend->age); | ||||
friend = bsearch((void *)30, &friends, array_size, sizeof(struct person), compare); | age = 30; | ||||
friend = bsearch(&age, friends, len, sizeof(friends[0]), compare); | |||||
assert(friend == NULL); | assert(friend == NULL); | ||||
printf("friend aged 30 not found\en"); | printf("friend aged 30 not found\en"); | ||||
return (EXIT_SUCCESS); | |||||
} | } | ||||
Done Inline ActionsThis return is not needed. kib: This return is not needed. | |||||
.Ed | .Ed | ||||
.Sh SEE ALSO | .Sh SEE ALSO | ||||
.Xr db 3 , | .Xr db 3 , | ||||
.Xr lsearch 3 , | .Xr lsearch 3 , | ||||
.Xr qsort 3 | .Xr qsort 3 | ||||
.\" .Xr tsearch 3 | .\" .Xr tsearch 3 | ||||
.Sh STANDARDS | .Sh STANDARDS | ||||
The | The | ||||
.Fn bsearch | .Fn bsearch | ||||
function conforms to | function conforms to | ||||
.St -isoC . | .St -isoC . |
Style(9) disallows initialization in declaration for locals. You cannot avoid it for const locals, but person_X vars are not const.
Casts should not have space after ')'.