Frage

Warum ist es "besser" zu verwenden g_strdup_printf, g_free, g_strcmp0 etc ... und Mitglibfunktionen?

War es hilfreich?

Lösung

Im Allgemeinen ist der Zweck von GLIB eine Nützlichkeits- und Portabilitätsbibliothek. Diejenigen an sich sind Gründe, es zu überlegen.

Die spezifischen Funktionen, die Sie erwähnen, bieten alle etwas zusätzlich zu ihren C -Standardbibliotheksvarianten:

  • g_strdup_printf ist wie sprintf, aber tatsächlich den Puffer für Sie zuteilt und Ihnen die Vermutung erspart, wie groß der Puffer sein sollte. (Der Rückgabewert sollte sein g_free'd.)
  • g_free ist wie free, aber überprüft einen Null-Zeiger.
  • g_strcmp0 ist wie strcmp, behandelt aber einen Null-Zeiger wie eine leere Schnur und sortiert ihn so vor.

Andere Tipps

Für konsistentes Verhalten in mehreren Betriebssystemen. Es ist eine Portabilitätssache.

In einigen anderen UNIX -Umgebungen als Linux oder wenn Ihr Programm unter Windows kompiliert wird, gibt es möglicherweise einige dieser Funktionen möglicherweise nicht oder verhalten sich im Zielbetriebsystem nicht anders.

Die Verwendung der GLIB -Versionen gewährleisten ein konsistentes Verhalten.

Ihr Verhalten ist auf jeder Plattform, die GTK+ unterstützt, genau definiert, im Gegensatz zu den nativen Funktionen, die möglicherweise manchmal auf der Teilung arbeiten.

Ich muss sagen, das ist gut beabsichtigt, aber nicht gut ausgeführt. Es ist irgendwie schön, dass Ihr Programm nicht abstürzt und brennt, wenn Sie versuchen, einen Zeiger mehr als einmal zu befreien (). Oder sortieren Sie eine Null -Zeichenfolge. Aber das ist ein gemischter Segen. Es hindert Sie daran, diese bösen Fehler auch in Ihrem Code zu entdecken. Sie werden es Ihnen nicht nur schwer fällt, Ihr Programm eines Tages portiert zu lassen, weil Sie sich auf nicht standardmäßige Funktionen verlassen, sondern Sie haben eine, Sie haben eine Ja wirklich schwer, weil Ihr Code fehlerhaft war und Sie es nie herausgefunden haben.

Der Glib bietet Portabilität und grundlegende Dinge, die Sie heutzutage von jeder Programmiersprache erwarten würden, z. B. Sammlungstypen (verknüpfte Listen, Arrays, Hash -Tabellen usw.). Hier sind einige der Vorteile, die Sie haben können.

Portabilität


Der Punkt des Glibs ist nicht zum C -Standard, sondern auf die Implementierungen des Standards tragbar. Der Glib kümmert sich um die bekannten Macken, die auf den ersten Blick nutzlos erscheinen mögen, bis Sie Ihren Code auf eine Plattform portieren müssen, die diese bösen Fehler enthält.

Nehmen wir das Beispiel von g_free, wie viele kritisieren es. Es gibt Plattformen, wo free(NULL) wird versagen, auch wenn C99 sagt, dass es funktionieren sollte. Dieser Scheck existiert seit mindestens 1998 (ich habe sie in der Git -Geschichte verfolgt). Einige mögen sagen, dass es nicht mehr benötigt wird, aber selbst im Jahr 2017 habe ich in einem Unternehmen gearbeitet, das nachprüft NULL voranrufen free Denn sonst würde es auf ihrer eingebetteten Plattform abstürzen. Es dient auch als Wrapper für die Intumentation Ihres Codes, wenn Sie ernsthafte Speicherdebugging durchführen möchten.

Lesbarkeit


Es hilft, die Lesbarkeit Ihres Codes zu verbessern, indem einige Wrapper -Funktionen bereitgestellt werden, die nicht nur die Portabitlität verbessern, sondern Ihnen auch hilft, viele Sprach Fallstricke zu vermeiden. Wie viele von Ihnen testen malloc Um zu sehen, ob es zurückkehrt NULL? Wie viele von Ihnen haben eine Möglichkeit, sich zu erholen, wenn es zurückkehrt NULL, da du grundlegend aus dem Gedächtnis bist?

g_malloc Wird die Anwendung abbrechen, wenn sie nicht zuordnen kann, was Sie wollen, und in vielen Anwendungen ist dies nur das gewünschte Verhalten. Für sehr große Zuordnungen, die möglicherweise scheitern, haben Sie g_try_malloc. Das ist das gleiche wie Malloc, gibt Ihnen jedoch immer noch den Vorteil, dass Sie eine Verpackung sind, die möglicherweise für die Instrumentierung verwendet werden kann.

In der Lage sein zu schreiben:

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

... frei und lässt den Entwickler die Aufgabe konzentrieren, die sie zu erreichen versucht. Es wird auch vermieden, dass Ihr Programm viel später abstürzt, weil es versucht, mit dem Schreiben zu schreiben NULL Zeiger und Sie müssen die Zuweisung aufspüren.

Die Standard -C -Bibliothek ist voller Fallen, und nicht jede einzelne Codezeile, die Sie schreiben, mikro verwalten müssen, ist eine Erleichterung. Lesen Sie einfach die Käfer Abschnitt der Manpages für einige Funktionen und Sie werden sehen. Wenn Sie weniger Kesselplattencode zum Überprüfen von Fehlern haben, wird der Code einfacher zu lesen, was die Wartbarkeit verbessert und weniger Fehler verursacht.

Merkmale


Ein weiterer Punkt ist der gesamte Haufen Sammlungstypen, den Glib bietet und dass Sie nicht neu eingestuft werden müssen. Nur weil das Neuauflagen eine verknüpfte Liste einfach ist, heißt das nicht, dass Sie es tun sollten. Ich habe in einem anderen Unternehmen gearbeitet, der Code mit mehreren verknüpften Listen -Implementierungen versandte, da einige Entwickler nur das haben würden Nicht hier erfunden Syndrom und würde ihre eigenen sanieren. Eine verbreitete, weit verbreitete Bibliothek wie GLIB hilft, diesen Unsinn zu vermeiden. Sie sollten dieses Zeug nicht sanieren, es sei denn, Sie haben sehr spezifische Leistungsbeschränkungen.

Vor 10 Jahren mag es Sinn gemacht haben, die Gnome Lib zu verwenden, aber es ist jetzt eine Vermächtnisverpflichtung. C89 ist wohl die Standardsprache der Welt mit sehr stabilen Funktionen und Syntax. Daher ist das Debuggen des C89 -Codes eines anderen machbar.

Im Gegensatz dazu ändert sich die Glib -Funktionen von Gnome außerhalb des C -Standards der Funktion.

Ausstellung A: g_snprintf ()

Eine sicherere Form der Standard -Sprintf () -Funktion. Es wird garantiert, dass die Ausgabe N -Zeichen nicht überschreitet (einschließlich des terminierenden NUL -Zeichens), sodass es leicht sicherzustellen, dass ein Pufferüberlauf nicht auftreten kann.

Siehe auch g_strdup_printf ().

In Versionen von GLIB vor 1.2.3 kann diese Funktion -1 zurückgeben, wenn die Ausgabe abgeschnitten wurde und die verkürzte Zeichenfolge möglicherweise nicht nulterminiert wird. In Versionen vor 1.3.12 gibt diese Funktion die Länge der Ausgangszeichenfolge zurück.

Der Rückgabewert von g_snprintf () entspricht der in ISO C99 standardisierten SnPrintf () -Funktion. Beachten Sie, dass sich dies von der traditionellen SNPrintf () unterscheidet, die die Länge der Ausgangszeichenfolge zurückgibt.

Die Formatzeichenfolge kann Positionsparameter enthalten, wie in der Einzel -UNIX -Spezifikation angegeben.

Ich bin weniger als begeistert, dass ich (noch eine) verknüpfte List schreiben kann, um Gnome zu ersetzen, und eine andere Version von SnPrintf () und einer Reihe beschissener Wrappercode, die lautlos malloc () S-Gedächtnis, wodurch das ein absolute Maxium gebrochen wird von C -Codierung: "Immer malloc () und free () im selben Bereich" So ersetzen Sie g_strdup_printf ().

g_strdup_printf ()

Ähnlich wie bei der Standard -C -Sprintf () -Funktion, aber sicherer, da er den erforderlichen maximalen Raum berechnet und den Speicher für das Ergebnis zuteilt. Die zurückgegebene Zeichenfolge sollte mit g_free () befreit werden, wenn sie nicht mehr benötigt werden.

Fügen Sie dazu den Nervenkitzel hinzu, eine massive Anzahl von Stringänderungen im Code vorzunehmen, um "nützliche" zu tun, um GCHAR in char, gint zu int, gboolean zu bool usw. usw. usw. zu ändern, bis meine Subversion -Vergleiche jetzt sind Telefonbuch. Schlimmer noch, Sie müssen am Ende immer mehr Code ändern, da dieses Zeug überall in den .h -Dateien übersät ist, sodass es sich wie eine Bootskorpse in ein großes Chaos erweitert.

Wenn Sie einen Vertragsjob umgehen und sehen glib.h Überall, rennen Sie !!!Sag einfach nein!.

PS: Laden Sie die Quelle herunter, entfernen Sie alle gnomspezifischen Typen und kompilieren Sie sie neu, um Ihr eigenes "g _" zu erstellen-weniger Funktionen, funktioniert irgendwie und ist ein großer Zeitlager.

Anlage B: g_strdup_printf ()

Schrecklicheres Gnom Crappola von Gnome. GNOME hat viele "schöne" Funktionen wie g_strdup_vprintf (), die "magisch" wissen, wie viel Speicher Sie Ihre zurückgekehrte Saite halten müssen, und ich hatte Gelegenheit, hinter die "Magie" zu schauen. Dies gewinnt meine Auszeichnung für den schrecklichsten Missbrauch von C aller Zeiten.

Wenn Sie weiterhin g_strdup_vprintf () durch alle Wrapper -Funktionen zurückverfolgen, kommen Sie zu diesem Juwel in 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;
}

Eine printf () -Funktion ist nicht nur langsamer als bei Absolute Null, sondern Sie werden feststellen, dass sie ein ganzes Byte, yup, einen ganzen GCHAR C, für die Aufbewahrung zuordnen, die Überlauf garantiert, sondern wen interessiert das? Sie bekommen die Länge der Saite, die sie für Malloc () benötigen - weil sie sich umdrehen und das gesamte printf () noch einmal machen - diesmal "magisch" mit gerade genug Speicher.

Sie werden natürlich +1 zu der Größe hinzufügen, sodass Sie Platz für einen Nul-Terminator haben, der natürlich auf schreckliche Kosten garantiert ist, aber sie haben es so tief in dem Code versteckt, dass sie Sie wetten. Ich gib einfach auf und benutze es blind und merke nicht, was für ein massives Gehirnfart das ist. Gee, danke Jungs. Ich liebe meinen Code einfach, um zu kriechen.

Lassen Sie sich nicht von der Funktion _g_vsnprintf () veröffentlichen, denn in gprintfint.h werden Sie feststellen, dass das kleine Juwel nur ein anderer Name für einfache alte Vanille vsnprintf () ist.

/* 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 ist dringend zu empfehlen, den Zauberer von Oz erneut zu beobachten, bevor Sie mit GNOME arbeiten. Sie werden also wissen, dass Sie nicht hinter den Vorhang schauen sollen. Willkommen in meinem Albtraum!

Jeder, der glaubt, dass Gnom stabiler ist als C, fehlt dem kritischen Denken schwer. Sie handeln Leistung und Transparenz für ein paar nette Dinge, die in der STL besser gemacht werden.

Hier ist ein Update. Es sieht aus, als der Entwickler ihren Fehler erkannt hat:

G_MEM_IS_SYSTEM_MALLOC wurde seit Version 2.46 veraltet und sollte nicht in neu geschriebenem Code verwendet werden.

GLIB verwendet immer das System Malloc, sodass diese Funktion immer wahr zurückgibt.

Überprüft, ob der von g_malloc () verwendete Allocator die Malloc -Implementierung des Systems ist. Wenn es mit malloc () ein echtes Speicher zurückgibt, kann man mit dem Speicher mit G_MALLOC () austauschbar austauschbar verwendet werden. Diese Funktion ist nützlich, um eine zusätzliche Kopie des zugewiesenen Speichers zu vermeiden, das von einer nicht-glibbasierten API zurückgegeben wird.

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top