There are such replacements in Pintos source

typedef bool list_less_func (const struct list_elem *a, const struct list_elem *b, void *aux); 

Why do I need to call the bool function name with arguments? The very use of this replacement is as follows:

  void list_insert_ordered (struct list *list, struct list_elem *elem, list_less_func *less, void *aux) { struct list_elem *e; ASSERT (list != NULL); ASSERT (elem != NULL); ASSERT (less != NULL); for (e = list_begin (list); e != list_end (list); e = list_next (e)) if (less (elem, e, aux)) break; return list_insert (e, elem); } 

It is not at all clear how such a "different name" bool works. Can you explain?

  • It's not entirely clear how these Pintos source codes managed to make return list_insert (e, elem); inside a function that returns void . If list_insert itself returns void , then such code would be valid in C ++. But in C is never allowed. - AnT

3 answers 3

You typedef not read.

 typedef bool list_less_func (const struct list_elem *a, const struct list_elem *b, void *aux); 

Here list_less_func is an alias for
bool(const struct list_elem *a, const struct list_elem *b, void *aux) , that is, for a function that takes three arguments and returns a bool .

Accordingly, list_less_func *less is a pointer to a function.

Without typedef it would look like this:
bool (*less)(const struct list_elem *a, const struct list_elem *b, void *aux) .

    In C, unlike C ++, there is no such built-in type as bool . There is a built-in _Bool integer type, which takes two values: 1 and 0.

    However, you can include the <stdbool.h> header in the program, which defines the macro bool , which expands as _Bool .

    From standard C (6.2.5 Types):

    2 An object is declared as the type 0 and 1.

    and (7.18 Boolean type and values)

    2 The macro

      bool 
     expands to _Bool. 

    In this ad

     typedef bool list_less_func (const struct list_elem *a, const struct list_elem *b, void *aux); 

    which is equivalent to an ad

     typedef _Bool list_less_func (const struct list_elem *a, const struct list_elem *b, void *aux); 

    if you remove the typedef keyword

     bool list_less_func (const struct list_elem *a, const struct list_elem *b, void *aux); 

    then we simply get a function declaration with the name list_less_func .

    So, this typedef introduces the symbolic name list_less_func for the type of the function, and not for the name bool , which, as I wrote, is defined in the heading <stdbool.h> , that is, for the type of function

     bool (const struct list_elem *a, const struct list_elem *b, void *aux); 

    which has three parameters and the return value is bool .

    This allows the declaration of the list_insert_ordered function list_insert_ordered concisely specify the type of the third parameter.

     void list_insert_ordered (struct list *list, struct list_elem *elem, list_less_func *less, void *aux); 

    as list_less_func * .

    Otherwise, without a typedef, you would have to write a very long declaration of the third parameter in the declaration of the list_insert_ordered function, for example,

     void list_insert_ordered (struct list *list, struct list_elem *elem, bool less (const struct list_elem *, const struct list_elem , void *), void *aux); 

    or how

     void list_insert_ordered (struct list *list, struct list_elem *elem, bool ( *less )(const struct list_elem *, const struct list_elem *, void *), void *aux); 

    That, you see, makes the declaration of the list_insert_ordered function difficult to read.

      There is no "call bool " and no "other name bool ". This ad has nothing to do with bool . The name that is defined in this case is not bool , but rather list_less_func . The list_less_func name will be a synonym for the function type.

       bool (const struct list_elem *, const struct list_elem *, void *) 

      (Lyrical digression: in the modern syntax of C ++, using using the same alias could be declared as

       using list_less_func = bool (const struct list_elem *, const struct list_elem *, void *); 

      )

      Further in the code this name is used to declare pointers to the following functional type: list_less_func * .

      Additionally, you can see that in the function parameter list, the functional type is automatically converted to the corresponding pointer type, i.e. could be used simply

       void list_insert_ordered (struct list *list, struct list_elem *elem, list_less_func less, void *aux) 

      without the extra * and the effect would be the same. But the author of the code decided to explicitly indicate this * . This is a matter of taste.


      Probably it was possible to turn on the "pointer" immediately right into the list_less_func type, i.e. initially announce

       typedef bool (* list_less_func)(const struct list_elem *a, const struct list_elem *b, void *aux); 

      and then write in the code simply list_less_func for declaring a pointer to a function. But this is a matter of taste.

      In this case, the author of the code decided not to hide the "pointer" under the typedef-name, which, in principle, is correct.


      On an abstract topic:

      In this code, this moment confuses

       return list_insert (e, elem); 

      inside a function that returns void . The C language does not allow the use of return with a parameter inside a function that returns void . This is not allowed even if list_insert also returns void . In the latter case, the code would be correct in C ++, but not in C.