Re: So You Think You Can Const?

Liste des GroupesRevenir à cl c 
Sujet : Re: So You Think You Can Const?
De : david.brown (at) *nospam* hesbynett.no (David Brown)
Groupes : comp.lang.c
Date : 09. Jan 2025, 10:35:52
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vlo59o$39tcu$1@dont-email.me>
References : 1 2 3 4 5 6 7 8
User-Agent : Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0
On 09/01/2025 05:24, Kaz Kylheku wrote:
On 2025-01-09, Ben Bacarisse <ben@bsb.me.uk> wrote:
Julio Di Egidio <julio@diegidio.name> writes:
>
static AvlTree_t const *AvlTree_node(
     void const *pk, AvlTree_t const *pL, AvlTree_t const *pR
) {
     AvlTree_t *pT;
>
     pT = malloc(sizeof(AvlTree_t));
>
     if (!pT) {
         return NULL;
     }
>
     pT->pk = pk;
     pT->pL = pL;
     pT->pR = pR;
>
     return pT;
}
>
Just on a side issue, I prefer to make tests like this positive so I'd
write:
>
  static AvlTree_t const *AvlTree_node(
      void const *pk, AvlTree_t const *pL, AvlTree_t const *pR
  ) {
      AvlTree_t *pT = malloc(*pT);
        if (pT) {
          pT->pk = pk;
          pT->pL = pL;
          pT->pR = pR;
      }
      return pT;
  }
 More generally:
     foo_handle *foo = foo_create();
    bar_handle *bar = foo ? bar_create(foo) : 0; // doesn't like null
    xyzzy_handle *xyz = xyzzy_create(42, bar, arg);
    container *con = malloc(sizeof *con);
     if (foo && bar && xyz && con) {
      // happy case: we have all three resources
       con->foo = foo;
      con->bar = bar;
      con->xyz = xyz;
       return con;
    }
     xyzzy_destroy(xyz);
    xyzzy_destroy(bar);
    if (foo)
       xyzzy_destroy(foo); // stupidly doesn't like null
     return 0;
 
I'm not going to "make a case" for this (though I will if you want!) --
I just think it helps to see lots of different styles.
 I might just have made the case. When more resources need to be
acquired that might fail, it consolidates the happy case under one
conjunctive test, and consolidates the cleanup in the unhappy case.
Effectively it's almost if we have only two cases.
 A minor disadvantage is that in the unhappy flow, we may allocate
resources past the point where it is obvious they are not going to be
needed: if foo_create() failed, we are pointlessly calling
xyzzy_create() and malloc for the container. It's possible that these
succeed, and we are just going to turn around and free them.
 
How about taking the idea slightly further and making the later allocations conditional too?
    foo_handle *foo = foo_create();
    bar_handle *bar = foo ? bar_create(foo) : 0; // doesn't like null
    xyzzy_handle *xyz = bar ? xyzzy_create(42, bar, arg) : 0;
    container *con = xyz ? malloc(sizeof *con) : 0;
    if (con) {
      // happy case: we have all three resources
    ...
If you are going to use that style (and I not arguing for or against it), go all in!

It's a form of consolidated error checking, like when we make
several system calls and check them for errors as a batch;
e.g. call fprintf several times and check for disk full (etc)
just once.
 

Date Sujet#  Auteur
6 Mar 26 o 

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal