freetype
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft] FT_Done_Face Should Not Return An Error


From: Lawrence D'Oliveiro
Subject: [ft] FT_Done_Face Should Not Return An Error
Date: Sat, 5 May 2018 21:54:22 +1200

It is common for object-disposal routines to never return error
statuses. The archetypal example is free(3)
<https://linux.die.net/man/3/free>. If this is passed a valid pointer,
it disposes of the object; if it is passed NULL, it quietly returns
without doing anything. If it is passed an invalid pointer, then this
indicates a program bug, so there is no point returning an error code
anyway: better to report an error message to stderr and even abort the
program.

Looking at the code for FT_Done_Face, from src/base/ftobjs.c:

      FT_EXPORT_DEF( FT_Error )
      FT_Done_Face( FT_Face  face )
      {
        FT_Error     error;
        FT_Driver    driver;
        FT_Memory    memory;
        FT_ListNode  node;


        error = FT_ERR( Invalid_Face_Handle );
        if ( face && face->driver )
        {
          face->internal->refcount--;
          if ( face->internal->refcount > 0 )
            error = FT_Err_Ok;
          else
          {
            driver = face->driver;
            memory = driver->root.memory;

            /* find face in driver's list */
            node = FT_List_Find( &driver->faces_list, face );
            if ( node )
            {
              /* remove face object from the driver's list */
              FT_List_Remove( &driver->faces_list, node );
              FT_FREE( node );

              /* now destroy the object proper */
              destroy_face( memory, face, driver );
              error = FT_Err_Ok;
            }
          }
        }

        return error;
      }

the only thing that can really go wrong is if the face cannot be
found among the driver’s memory blocks. Clearly something has gone
catastrophically wrong in this case, so it makes sense to report an
error and abort the program.

Otherwise, if it is passed NULL, it should just quietly return without
doing anything. This makes it easier to write code that initializes all
temporary pointers up front and unconditionally disposes them at the
end; there is no need to tediously check everything for NULL pointers,
because the disposal routines will take care of that.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]