Pregunta

Mientras que la programación en C y GTK +, ¿por qué es "mejor" para usar g_strdup_printf, g_free, g_strcmp0 etc ... y su compañero funciones GLib?

¿Fue útil?

Solución

En general, el propósito de GLib es una utilidad y portabilidad biblioteca. Los que están en sí son razones para considerar el uso de la misma.

Las funciones específicas que usted menciona todos ofrecen algo extra en la parte superior de sus variantes de la biblioteca estándar de C:

  • g_strdup_printf es como sprintf, pero en realidad reserva el buffer para usted y le ahorra las conjeturas de cuán grande es el tampón debe ser. (El valor de retorno debe ser g_free'd.)
  • g_free es como free, pero los controles de un NULL-puntero.
  • g_strcmp0 es como strcmp, pero trata a un NULL-puntero como una cadena vacía, y por lo tanto ordena delante.

Otros consejos

Para un comportamiento coherente en múltiples sistemas operativos. Es una cosa portabilidad.

En algunos otros entornos Unix diferente de Linux, o si su programa es compilado en las ventanas, algunas de esas funciones pueden no existir o se comportan de manera diferente en el sistema operativo de destino.

El uso de las versiones simplistas garantizar un comportamiento coherente.

Su comportamiento está bien definido en cualquier plataforma que soporte GTK +, en contraposición a las funciones nativas que pueden tal vez trabajo a veces hasta la mitad.

Tengo que decir que esto está bien intencionada pero no está bien ejecutado. Es sorta agradable que el programa no estrellarse y arder cuando intenta liberar () un puntero más de una vez. U ordenar una cadena nula. Pero eso es un arma de doble filo. Se le impide descubrir estos insectos desagradables en su código. No sólo va a tener dificultades para conseguir su programa portado algún día, porque usted está confiando en funciones no estándar, tendrá un realmente momento difícil debido a que su código era defectuoso y nunca se encontró a cabo.

El GLib proporciona portabilidad y cosas básicas que esperas hoy en día desde cualquier lenguaje de programación, como tipos de colecciones (listas enlazadas, matrices, tablas hash, etc.). Éstos son algunos de los beneficios GLib le puede dar.

Portabilidad


El punto de la GLib es para ser portátil no al nivel C, pero a las implementaciones de la norma. El GLib se encarga de las peculiaridades conocidos que podrían parecer inútil a primera vista hasta que tenga que portar su código para una plataforma que tiene esos bichos repugnantes.

Tomemos el ejemplo de g_free, como muchos lo critican. Hay plataformas en las que se producirá un error free(NULL) , incluso si C99 dice que debería funcionar. existe el registro de entrada desde al menos 1998 (Rastreé que en la historia GIT). Algunos pueden decir que no se necesita más, pero incluso en el año 2017 trabajé en una compañía que comprueba NULL antes de llamar free porque de lo contrario se estrellaría en su plataforma integrada. También sirve como un contenedor para Intrumentation de su código cuando se quiere hacer algo de depuración de memoria grave.

legibilidad


Esto ayuda a mejorar la legibilidad del código, proporcionando algunas funciones de contenedor que no sólo mejoran portabitlity, sino que también ayudan a evitar muchas trampas del lenguaje. ¿Cuántos de ustedes malloc prueba para ver si devuelve NULL? ¿Cuántos de ustedes tienen una forma de recuperar si devuelve NULL, ya que estás básicamente sin memoria?

g_malloc abortará la aplicación si no se puede asignar lo que quiere, y en muchas aplicaciones, esto es sólo el comportamiento que desea. Por muy grandes asignaciones que pueden fallar, que ha g_try_malloc. Ese es el mismo que malloc, pero todavía le da la ventaja de ser un envoltorio que puede ser utilizado para la instrumentación.

Ser capaz de escribir:

char *buffer = g_malloc(30);
/* Do something with it ... */
g_free (buffer);

... libera la mente y permite que el desarrollador enfoque en la tarea que está tratando de lograr. También evita que su caída del programa mucho más tarde porque está tratando de escribir usando puntero NULL y hay que rastrear la asignación.

La biblioteca estándar de C está lleno de trampas, y no tener que gestionar micro cada línea de código que escriba es un alivio. Basta con leer los FALLOS de las páginas de manual para algunas funciones y youo'll ver. Tener menos de código repetitivo para comprobar los errores hace que el código más fácil de leer, lo que mejora la capacidad de mantenimiento, y causa menos errores.

Características


Otro punto es el montón de tipos de colección GLib proporciona y que usted no tiene que volver a implementar. El hecho de que reimplementar una lista enlazada es fácil no significa que debe hacerlo. I trabajado en otra empresa que se incluye código con varias implementaciones lista enlazada, debido a que algunos desarrolladores de sólo tendría el No inventado aquí síndrome y se re-desarrollar su propio. A, Thouroughly probado, biblioteca generalizado común, como GLib ayuda a evitar este absurdo. No se debe volver a desarrollar esas cosas a menos que tenga restricciones de rendimiento muy específicos.

Hace 10 años, el uso de la lib Gnome puede haber tenido sentido, pero su ahora un pasivo legado. C89 es posiblemente la lengua más habitual en el mundo, con características muy estables y la sintaxis, por lo que el código C89 depuración de otra persona es factible.

Por contraste cambios simplistas de Gnome Es características de función fuera de la Norma C, por lo que no sólo se llega a hacer frente a la depuración de código de contenedor oscura hecha de C, pero su código puede dejar de funcionar debido a Gnome cambia de funciones de contenedor.

Exhibit A: g_snprintf ()

  

una forma más segura de la función sprintf estándar (). La salida es   garantizada para no exceder n caracteres (incluyendo la terminación NUL   personaje), por lo que es fácil asegurar que un desbordamiento de búfer no puede   ocurrir.

     

Ver también g_strdup_printf ().

     

En versiones de GLib anteriores a 1.2.3, esta función puede devolver -1 si el   salida fue truncado, y la cadena truncada puede no ser   nul terminados. En las versiones anteriores a 1.3.12, esta función devuelve el   longitud de la cadena de salida.

     

El valor de retorno de g_snprintf () se ajusta a la función snprintf ()   como normalizado en ISO C99. Tenga en cuenta que esto es diferente de   snprintf tradicional (), que devuelve la longitud de la cadena de salida.

     

El formato de cadena puede contener parámetros de posición, como se especifica en   la Single Unix Specification.

Estoy menos que encantados llego a escribir (otra)-lista enlazada para reemplazar Gnome de, y sin embargo, otra versión de snprintf () y un montón de código de contenedor de mierda que silenciosamente malloc (memoria) s, rompiendo así el uno maxium absoluta de codificación C:. "siempre malloc () y conexión () en el mismo ámbito" para reemplazar g_strdup_printf ()

  

g_strdup_printf ()

     

Al igual que en el sprintf C estándar de la función () pero más seguro, ya que calcula el máximo espacio requerido y asigna memoria para mantener el resultado. La cadena devuelta debe estar   liberado con g_free () cuando ya no sean necesarios.

Añadir a esto la emoción de hacer un número masivo de cambios en cadenas en el código para hacer cosas "útiles", como el cambio gchar a Char, gint a int, gboolean a bool, etc, etc, etc, hasta la saciedad hasta que mis comparaciones Subversion ahora son una guía telefónica. Peor aún, al final tener que cambiar más y más código, porque esto está llena de todo los archivos .h, por lo que se mantiene en expansión, como un cadáver boated, en un gran lío.

Si va a la determinación del alcance de un contrato de trabajo y ver glib.h en cualquier lugar, RUN !!! Sólo decir que no!.

PS: Descarga de la fuente, la eliminación de todos los tipos de Gnome-específicas, y volver a compilar para hacer su propia "g _" - menos funciones sorta, algo que funciona y es un gran ahorro de tiempo.

Exhibit B: g_strdup_printf ()

Más horrible crappola Gnome de Gnome. Gnome tiene un montón de funciones "Lovely" como g_strdup_vprintf () que "mágicamente" saber la cantidad de almacenamiento que necesita para mantener su cadena devuelta, y tuve ocasión de mirar detrás de la "magia". Este gana mi premio a la más horrible abuso de C nunca.

Si se mantiene el rastreo g_strdup_vprintf () de nuevo a través de todas las funciones de contenedor, se llega a esta joya en gmessages.c ....

/**
 * g_printf_string_upper_bound:
 * @format: the format string. See the printf() documentation
 * @args: the parameters to be inserted into the format string
 *
 * Calculates the maximum space needed to store the output
 * of the sprintf() function.
 *
 * Returns: the maximum space needed to store the formatted string
 */
gsize
g_printf_string_upper_bound (const gchar *format,
                             va_list      args)
{
  gchar c;
  return _g_vsnprintf (&c, 1, format, args) + 1;
}

No sólo es cualquier función printf () más lento que los mocos en el cero absoluto, se dará cuenta de que asignan un byte entero, sip, toda una gchar c, para el almacenamiento, lo que garantiza desbordamiento, pero a quién le importa? consiguen la longitud de la cadena que tendrán que malloc () - porque van a dar la vuelta y hacer todo el printf () de nuevo - esta vez, "mágicamente" con suficiente almacenamiento.

Van a añadir 1 al tamaño, por supuesto, por lo que tendrá espacio para una nul-terminador, garantizado, a expensas horrible, por supuesto, pero han escondido tan profundo en el código que están seguros de que le dan por vencidos y usarlo a ciegas y no darse cuenta de lo que es unamasiva del cerebro pedo que es esto. Gee, gracias chicos. Me encanta mi código a gatear.

No deje que el _g_vsnprintf () función te desanime, ya que en gprintfint.h descubrirá que pequeña joya es sólo otro nombre para vsnprintf llanura de vainilla de edad ();

/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GLib Team and others 2002.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
 */

#ifndef __G_PRINTFINT_H__
#define __G_PRINTFINT_H__

#ifdef HAVE_GOOD_PRINTF

#define _g_printf    printf
#define _g_fprintf   fprintf
#define _g_sprintf   sprintf
#define _g_snprintf  snprintf

#define _g_vprintf   vprintf
#define _g_vfprintf  vfprintf
#define _g_vsprintf  vsprintf
#define _g_vsnprintf vsnprintf

#else

#include "gnulib/printf.h"

#define _g_printf    _g_gnulib_printf
#define _g_fprintf   _g_gnulib_fprintf
#define _g_sprintf   _g_gnulib_sprintf
#define _g_snprintf  _g_gnulib_snprintf

#define _g_vprintf   _g_gnulib_vprintf
#define _g_vfprintf  _g_gnulib_vfprintf
#define _g_vsprintf  _g_gnulib_vsprintf
#define _g_vsnprintf _g_gnulib_vsnprintf

#endif

#endif /* __G_PRINTF_H__ */

Es muy recomendable que usted mira el mago de Oz de nuevo antes de trabajar con Gnome, para que sepa no mirar detrás de la cortina. Bienvenido a mi pesadilla!

Cualquier persona que piensa que Gnome es más estable que C es gravemente deficiente en el pensamiento crítico. Que el comercio desempeño y la transparencia de algunas cosas buenas que se hacen mejor en la STL.

Esta es una actualización. Parece dado cuenta de su error del desarrollador:

  
    

g_mem_is_system_malloc ha quedado obsoleto desde la versión 2.46 y no debe ser utilizado en el código recién escrito.

  
     

GLib siempre utiliza el sistema de malloc, por lo que esta función siempre devuelve TRUE.

     

Comprueba si el asignador utilizado por g_malloc () es la implementación de malloc del sistema. Si devuelve memoria TRUE asignado con malloc () se puede utilizar intercambiable con memoria asignada usando g_malloc (). Esta función es útil para evitar una copia extra de memoria asignada devuelto por una API no basado en GLib.

https: // developer.gnome.org/glib/stable/glib-Memory-Allocation.html#g-mem-is-system-malloc

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top