g_strdup_printf
C および GTK+ でプログラミングしているときに、g_free
、などを使用する方が「良い」のはなぜg_strcmp0
ですか?
7 に答える
一般に、GLib の目的はユーティリティと移植性のライブラリです。それら自体が、それを使用することを検討する理由です。
あなたが言及した特定の関数はすべて、C 標準ライブラリのバリアントに加えて何か特別なものを提供します。
g_strdup_printf
に似sprintf
ていますが、実際にバッファを割り当てて、バッファの大きさを推測する手間を省きます。(戻り値はg_free
'd である必要があります。)g_free
に似free
ていますが、NULL ポインターをチェックします。g_strcmp0
に似strcmp
ていますが、NULL ポインターを空の文字列のように扱い、前に並べ替えます。
複数のオペレーティング システムで一貫した動作を実現します。携帯性のモノです。
Linux 以外の一部の UNIX 環境、またはプログラムが Windows でコンパイルされている場合、これらの関数の一部が存在しないか、ターゲット オペレーティング システムで異なる動作をする可能性があります。
glib バージョンを使用すると、一貫した動作が保証されます。
それらの動作は、GTK+ がサポートするすべてのプラットフォームで明確に定義されており、部分的に動作する可能性があるネイティブ関数とは対照的です。
私は言わなければならない、これはよく意図されていますが、うまく実行されていません。ポインターを複数回 free() しようとしても、プログラムがクラッシュしたり燃えたりしないのは、ちょっといいことです。または、NULL 文字列をソートします。しかし、それは複雑な祝福です。コード内でこれらの厄介なバグを発見することもできなくなります。非標準関数に依存しているため、いつかプログラムを移植するのに苦労するだけでなく、コードにバグがあり、それを見つけることができなかったために、非常に苦労するでしょう。
10 年前には、Gnome lib を使用することは理にかなっていたかもしれませんが、今ではレガシー責任です。C89 は間違いなく世界で最も標準的な言語であり、非常に安定した機能と構文を備えているため、他の人の C89 コードをデバッグすることは可能です。
対照的に、Gnome の glib は C 標準外の関数の機能を変更するため、C で作成されたあいまいなラッパー コードのデバッグに対処できるだけでなく、Gnome がラッパー関数を変更するため、コードが動作しなくなる可能性があります。
資料 A: g_snprintf()
標準の sprintf() 関数のより安全な形式。出力は n 文字 (終端のヌル文字を含む) を超えないことが保証されているため、バッファー オーバーフローが発生しないことを簡単に確認できます。
g_strdup_printf() も参照してください。
1.2.3 より前のバージョンの GLib では、出力が切り捨てられた場合、この関数は -1 を返すことがあり、切り捨てられた文字列は nul で終了しない場合があります。1.3.12 より前のバージョンでは、この関数は出力文字列の長さを返します。
g_snprintf() の戻り値は、ISO C99 で標準化されている snprintf() 関数に準拠しています。これは、出力文字列の長さを返す従来の snprintf() とは異なることに注意してください。
フォーマット文字列には、Single Unix Specification で指定されているように、位置パラメータを含めることができます。
Gnomeのものを置き換えるために(さらに別の)リンクリストを作成し、さらに別のバージョンのsnprintf()と、静かにmalloc()のメモリを壊すくだらないラッパーコードの束を書くことに興奮していません。 C コーディングの説明: 「常に malloc() と free() は同じスコープ内に」 g_strdup_printf() を置き換えます。
g_strdup_printf ()
標準の C sprintf() 関数に似ていますが、必要な最大スペースを計算し、結果を保持するためにメモリを割り当てるため、より安全です。返された文字列は、不要になったら g_free() で解放する必要があります。
これに加えて、gchar を char に、gint を int に、gboolean を bool に変更するなどの「有用な」ことを行うために、コード内で大量の文字列を変更するスリルを加えて、Subversion の比較が完全になるまでうんざりします。電話帳。さらに悪いことに、このようなものが .h ファイル全体に散らばっているため、ますます多くのコードを変更する必要が生じます。
コントラクトジョブをスコープしていて、glib.h がどこかにある場合は、実行してください!!! いやだっていうだけだよ!。
PS:ソースをダウンロードし、すべての Gnome 固有の型を削除し、それを再コンパイルして独自の "g_" を使用しない関数を作成すると、ある程度は機能し、時間を大幅に節約できます。
証拠 B: g_strdup_printf()
Gnome からのより恐ろしい Gnome crappola。Gnome には g_strdup_vprintf() のような「素敵な」関数がたくさんあり、返された文字列を保持するためにどれだけのストレージが必要かを「魔法のように」知ることができます。これは、これまでで最も恐ろしいCの乱用に対して私の賞を受賞しました。
すべてのラッパー関数を通して g_strdup_vprintf() をトレースし続けると、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;
}
すべての printf() 関数は、絶対ゼロで snot よりも遅いだけでなく、オーバーフローを保証するストレージにバイト全体、yup、gchar c 全体を割り当てることに気付くでしょうが、誰が気にしますか? malloc() に必要な文字列の長さを取得します。これは、向きを変えて printf() 全体をもう一度実行するためです。今回は、「魔法のように」十分なストレージを使用します。
もちろん、彼らはサイズに+1を追加するので、nulターミネータの余地が保証されますが、もちろん恐ろしい費用がかかります.あきらめて盲目的に使用するだけで、これがどんなに大きな脳のおならであるかに気付かない. ええ、ありがとうみんな。コードをクロールするのが大好きです。
_g_vsnprintf() 関数に惑わされないでください。なぜなら、gprintfint.h では、小さな宝石が単純な古いバニラの 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__ */
Gnome を使用する前に、オズの魔法使いをもう一度見ることを強くお勧めします。私の悪夢へようこそ!
Gnome が C よりも安定していると考える人は、批判的思考がひどく欠けています。パフォーマンスと透過性を引き換えに、STL でより適切に行われるいくつかの優れた機能を利用できます。