c - learn - instalar gtk en windows
¿Por qué usar las funciones de GLib? (7)
Aquí hay una actualización. Parece que el desarrollador se dio cuenta de su error:
g_mem_is_system_malloc ha quedado en desuso desde la versión 2.46 y no debe usarse en el código recién escrito.
GLib siempre usa el sistema malloc, por lo que esta función siempre devuelve VERDADERO.
Comprueba si el asignador utilizado por g_malloc () es la implementación de malloc del sistema. Si retorna la memoria VERDADERA asignada con malloc () se puede usar intercambiable con la memoria asignada usando g_malloc (). Esta función es útil para evitar una copia adicional de la memoria asignada devuelta por una API no basada en GLib.
https://developer.gnome.org/glib/stable/glib-Memory-Allocation.html#g-mem-is-system-malloc
Al programar en C y GTK +, ¿por qué es "mejor" usar g_strdup_printf
, g_free
, g_strcmp0
, etc. y otras funciones de GLib?
Debo decir que esto está bien intencionado pero no bien ejecutado. Es bueno que tu programa no se bloquee y se queme cuando intentas liberar () un puntero más de una vez. O ordena una cadena NULA. Pero eso es una bendición mixta. También evita que descubras estos errores desagradables en tu código. No solo tendrá dificultades para que su programa sea portado algún día, ya que confía en funciones no estándar, también tendrá dificultades porque su código tenía errores y nunca lo descubrió.
El GLib proporciona portabilidad y cosas básicas que usted esperaría hoy en día desde cualquier lenguaje de programación, como tipos de colección (listas vinculadas, matrices, tablas hash, etc.). Estos son algunos de los beneficios que GLib puede brindarle.
Portabilidad
El punto de la GLib es ser portátil no al estándar C, sino a las implementaciones del estándar. El GLib se encarga de las peculiaridades conocidas que pueden parecer inútiles a primera vista hasta que necesite llevar su código a una plataforma que tenga esos errores desagradables.
Tomemos el ejemplo de g_free
, como muchos lo critican. .com/a/1938758/518853 , incluso si C99 dice que debería funcionar. Ese cheque existe desde al menos 1998 (lo rastreé en el historial de git). Algunos pueden decir que ya no es necesario, pero incluso en 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 envoltorio para la instrumentación de su código cuando desea realizar una grave depuración de memoria.
Legibilidad
Ayuda a mejorar la legibilidad de su código al proporcionar algunas funciones de envoltura que no solo mejoran la portabilidad, sino que también lo ayudan a evitar muchos problemas de idioma. ¿Cuántos de ustedes prueban malloc
para ver si devuelve NULL
? ¿Cuántos de ustedes tienen una manera de recuperarse si devuelve NULL
, ya que básicamente está fuera de la memoria?
g_malloc
la aplicación si no puede asignar lo que desea, y en muchas aplicaciones, este es el comportamiento que desea. Para asignaciones muy grandes que pueden fallar, tienes g_try_malloc
. Es lo mismo que malloc, pero aún así le brinda la ventaja de ser un envoltorio que se puede usar para la instrumentación.
Poder escribir:
char *buffer = g_malloc(30);
/* Do something with it ... */
g_free (buffer);
... libera la mente y permite que el desarrollador se concentre en la tarea que está tratando de lograr. También evita que su programa se bloquee mucho más tarde porque está intentando escribir con el puntero NULL
y tiene que rastrear la asignación.
La biblioteca estándar de C está llena de trampas, y no tener que microgestionar cada línea de código que escriba es un alivio. Simplemente lea la sección FALLOS de las páginas de manual para algunas funciones y verá. Tener menos código repetitivo para verificar errores hace que el código sea más fácil de leer, lo que mejora la capacidad de mantenimiento y causa menos errores.
Caracteristicas
Otro punto es el conjunto completo de tipos de colección que proporciona GLib y que no tiene que volver a implementar. El hecho de que volver a implementar una lista enlazada sea fácil no significa que deba hacerlo. Trabajé en otra compañía que enviaba código con varias implementaciones de listas vinculadas, porque algunos desarrolladores solo tendrían el síndrome de No inventó aquí y volverían a desarrollar el suyo. Una biblioteca común, exhaustivamente probada y extendida como GLib ayuda a evitar este disparate. No debe volver a desarrollar esas cosas a menos que tenga restricciones de rendimiento muy específicas.
En general, el propósito de GLib es una biblioteca de utilidad y portabilidad. Aquellos en sí mismos son razones para considerar su uso.
Las funciones específicas que mencionas ofrecen algo adicional sobre sus variantes de biblioteca estándar de C:
-
g_strdup_printf
es comosprintf
, pero en realidad le asigna el búfer y le ahorra las conjeturas de qué tan grande debe ser el búfer. (El valor de retorno debe serg_free
''d.) -
g_free
es comofree
, pero busca un puntero NULL. -
g_strcmp0
es comostrcmp
, pero trata un puntero NULL como una cadena vacía y, por lo tanto, la ordena al frente.
Hace 10 años, el uso de Gnome lib puede haber tenido sentido, pero ahora es un pasivo heredado. C89 es posiblemente el lenguaje más estándar del mundo, con características y sintaxis muy estables, por lo que es posible depurar el código C89 de otra persona.
Por el contrario, el glib de Gnome cambia las funciones de su función fuera del estándar C, por lo que no solo tiene que lidiar con la depuración del oscuro código envoltorio hecho de C, sino que su código puede dejar de funcionar porque Gnome cambia sus funciones de envoltorio.
Anexo A: g_snprintf ()
Una forma más segura de la función sprintf () estándar. Se garantiza que la salida no exceda de n caracteres (incluido el carácter nulo de terminación), por lo que es fácil garantizar que no se produzca un desbordamiento del búfer.
Véase también g_strdup_printf ().
En las versiones de GLib anteriores a 1.2.3, esta función puede devolver -1 si la salida se truncó y la cadena truncada no puede terminar en nulo. En versiones anteriores a 1.3.12, esta función devuelve la longitud de la cadena de salida.
El valor de retorno de g_snprintf () se ajusta a la función snprintf () según lo estandarizado en ISO C99. Tenga en cuenta que esto es diferente de snprintf () tradicional, que devuelve la longitud de la cadena de salida.
La cadena de formato puede contener parámetros posicionales, como se especifica en la Especificación Unix única.
Estoy menos que entusiasmado. Tengo que escribir (otro) lista de enlaces para reemplazar Gnome, Y otra versión de snprintf () y un montón de código de envoltorio de mierda que silenciosamente malloc () s memoria, rompiendo así el absoluto máximo absoluto. de la codificación C: "Siempre malloc () y free () en el mismo ámbito" para reemplazar g_strdup_printf ().
g_strdup_printf ()
Similar a la función estándar C sprintf () pero más segura, ya que calcula el espacio máximo requerido y asigna memoria para retener el resultado. La cadena devuelta debe liberarse con g_free () cuando ya no sea necesaria.
Agregue a esto la emoción de hacer un gran número de cambios de cadena en el código para hacer cosas "útiles" como cambiar gchar a char, gint a int, gboolean a bool, etc, etc, etc, etcétera, hasta que mis comparaciones de Subversion sean ahora una directorio telefónico. Peor aún, terminas teniendo que cambiar cada vez más el código porque este material está lleno en todos los archivos .h, por lo que sigue expandiéndose, como un cadáver, en un gran lío.
Si estás buscando un trabajo por contrato y ves glib.h en cualquier lugar, ¡ CORRE ! ¡Solo di no!.
PD: descargar la fuente, eliminar todos los tipos específicos de Gnome y volver a compilar para hacer su propio "g _" - menos funciones sorta, un poco funciona, y es un gran ahorro de tiempo.
Anexo B: g_strdup_printf ()
Más horrible gnome crappola de Gnome. Gnome tiene muchas funciones "encantadoras" como g_strdup_vprintf () que "mágicamente" sabe cuánto almacenamiento necesitas para mantener tu cadena devuelta, y tuve la oportunidad de mirar detrás de la "magia". Esto gana mi premio por el abuso más horrible de C nunca.
Si sigues rastreando g_strdup_vprintf () a través de todas las funciones de envoltorio, vienes a esta gema 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;
}
CUALQUIER función printf () no solo es más lenta que la muda en el cero absoluto, también notará que asignan un byte completo, yup, un gchar c completo, para el almacenamiento, lo que garantiza el desbordamiento, pero ¿a quién le importa? obtienen la longitud de la cadena que necesitarán para malloc (), porque van a dar la vuelta y volver a hacer todo el printf () una vez más, esta vez, "mágicamente" con el almacenamiento suficiente.
Por supuesto, agregarán +1 al tamaño, por lo que tendrá espacio para un terminador nulo, por supuesto, a un costo horrible, por supuesto, pero lo han escondido tan profundamente en el código que le están apostando. Simplemente me doy por vencido y lo uso a ciegas y no me doy cuenta de lo que es un gran problema mental. Caramba, gracias chicos. Me encanta mi código para rastrear.
No dejes que la función _g_vsnprintf () te desanime, porque en gprintfint.h descubrirás que la pequeña joya es solo otro nombre para vainilla vsnprintf ();
/* 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__ */
Se recomienda encarecidamente que vuelvas a ver el Mago de Oz antes de trabajar con Gnome, por lo que sabrás que no debes mirar detrás de la cortina. ¡Bienvenido a mi pesadilla!
Cualquiera que piense que Gnome es más estable que C carece de pensamiento crítico. Cambia el rendimiento y la transparencia por algunas cosas agradables que se hacen mejor en la STL.
Para un comportamiento consistente en múltiples sistemas operativos. Es una cosa de la portabilidad.
En otros entornos Unix distintos de Linux, o si su programa está compilado en Windows, es posible que algunas de esas funciones no existan o se comporten de manera diferente en el sistema operativo de destino.
El uso de las versiones glib asegura un comportamiento consistente.
Su comportamiento está bien definido en cualquier plataforma que soporta GTK +, a diferencia de las funciones nativas que a veces pueden funcionar parcialmente.