Подтвердить что ты не робот

Зачем использовать функции GLib?

При программировании на C и GTK +, почему "лучше" использовать g_strdup_printf, g_free, g_strcmp0 и т.д.... и другие функции GLib?

4b9b3361

Ответ 1

В общем, цель GLib - это утилита и библиотека переносимости. Это само по себе является основанием для рассмотрения его использования.

Конкретные функции, о которых вы говорите, предлагают что-то дополнительное в дополнение к их вариантам стандартной библиотеки C:

  • g_strdup_printf похож на sprintf, но на самом деле выделяет вам буфер и сохраняет догадки о том, насколько большой буфер должен быть. (Возвращаемое значение должно быть g_free 'd.)
  • g_free похож на free, но проверяет NULL-указатель.
  • g_strcmp0 похож на strcmp, но обрабатывает NULL-указатель, как пустую строку, и таким образом сортирует его спереди.

Ответ 2

Для последовательного поведения в нескольких операционных системах. Это вещь переносимости.

В некоторых других средах unix, отличных от Linux, или если ваша программа скомпилирована в Windows, некоторые из этих функций могут не существовать или вести себя по-разному в целевой операционной системе.

Использование glib-версий обеспечивает согласованное поведение.

Ответ 3

Их поведение хорошо определено на любой платформе, поддерживаемой GTK +, в отличие от нативных функций, которые могут иногда работать частично.

Ответ 4

Я должен сказать, что это хорошо продуманный, но плохо выполненный. Приятно, что ваша программа не будет разбиваться и гореть, когда вы пытаетесь освободить() указатель более одного раза. Или соберите строку NULL. Но это смешанное благословение. Это мешает вам обнаружить эти неприятные ошибки в вашем коде. Мало того, что вам нелегко будет когда-нибудь переносить вашу программу, потому что вы полагаетесь на нестандартные функции, вам будет очень тяжело, потому что ваш код был глючит, и вы никогда не узнали.

Ответ 5

GLib обеспечивает переносимость и основные функции, которые вы ожидаете в настоящее время на любом языке программирования, например, типы коллекций (связанные списки, массивы, хэш-таблицы и т.д.). Вот некоторые из преимуществ, которые может дать вам GLib.

Портативность


Точка GLib должна быть переносимой не на стандарт C, а на реализацию стандарта. GLib заботится о известных причудах, которые могут показаться бесполезными с первого взгляда, пока вам не понадобится переносить свой код на платформу с этими неприятными ошибками.

Давайте рассмотрим пример g_free, так как многие критикуют его. Существуют платформы, где free(NULL) не удастся, даже если C99 говорит, что он должен работать. Эта проверка существует, по крайней мере, с 1998 года (я отслеживал ее в истории git). Некоторые могут сказать, что это больше не нужно, но даже в 2017 году я работал в компании, которая проверяет NULL перед вызовом free, потому что в противном случае она потерпит крах на их встроенной платформе. Он также служит в качестве обертки для инкрустации вашего кода, когда вы хотите провести серьезную отладку памяти.

читаемость


Это помогает улучшить читабельность вашего кода, предоставляя некоторые функции-обертки, которые не только улучшают портативность, но также помогают избежать многих языковых ошибок. Сколько из вас проверили malloc, чтобы узнать, возвращает ли он NULL? У многих из вас есть способ восстановить, если он возвращает NULL, так как вы в основном отстаете от памяти?

g_malloc отменяет приложение, если оно не может выделить то, что вы хотите, и во многих приложениях это именно то поведение, которое вы хотите. Для очень больших распределений, которые могут потерпеть неудачу, у вас есть g_try_malloc. Это то же самое, что и malloc, но все же дает вам преимущество быть оберткой, которая может быть использована для инструментария.

Возможность писать:

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

... освобождает ум и позволяет разработчику сосредоточиться на задаче, которую она пытается достичь. Это также позволяет избежать сбоя вашей программы намного позже, потому что она пытается писать с помощью указателя NULL, и вам нужно отслеживать распределение.

Стандартная библиотека C полна ловушек, и не нужно микро-управлять каждой отдельной строкой кода, которую вы пишете, является облегчением. Просто прочитайте раздел "ОШИБКИ" в manpages для некоторых функций, и вы увидите. Имея меньше кода шаблона для проверки ошибок, код проще читать, что улучшает ремонтопригодность и вызывает меньше ошибок.

Функции


Еще один момент - это совокупность типов коллекций GLib, которые вам не нужно переопределять. Просто потому, что переопределение связанного списка легко не означает, что вы должны это делать. Я работал в другой компании, которая отправила код с несколькими связанными реализациями списков, потому что у некоторых разработчиков был бы синдром Not Invented Here и он переработал бы свои собственные. Обычная, тщательно протестированная широко распространенная библиотека, такая как GLib, помогает избежать этой бессмыслицы. Вы не должны переделывать этот материал, если у вас нет особых ограничений производительности.

Ответ 6

10 лет назад использование библиотеки Gnome могло иметь смысл, но теперь она является наследственной ответственностью. C89, пожалуй, самый стандартный язык в мире, с очень стабильными функциями и синтаксисом, поэтому отладка другого кода C89 выполнима.

В отличие от Gnome glib, он изменяет функции функции вне C-стандарта, поэтому вы не только имеете дело с отлаживанием неясного кода-оболочки из C, но ваш код может перестать работать, потому что Gnome изменяет его функции-обертки.

Иллюстрация A: g_snprintf()

Более безопасная форма стандартной функции sprintf(). Выход гарантированно не превышать n символов (включая завершающий нуль символ), поэтому легко убедиться, что переполнение буфера не может происходят.

См. также g_strdup_printf().

В версиях GLib до 1.2.3 эта функция может возвращать -1, если вывод был усечен, и усеченная строка может не быть NUL-прекращается. В версиях до 1.3.12 эта функция возвращает длина выходной строки.

Возвращаемое значение g_snprintf() соответствует функции snprintf() как стандартизован в ISO C99. Обратите внимание, что это отличается от традиционный snprintf(), который возвращает длину выходной строки.

Строка формата может содержать позиционные параметры, как указано в Спецификация Single Unix.

Я не в восторге, мне нужно написать (еще один) связанный список, чтобы заменить Gnome's, и еще одну версию snprintf() и кучу дерьмового кода обертки, который молчал память malloc(), тем самым нарушая один абсолютный максимум C-кода: "Всегда malloc() и free() в той же области действия, чтобы заменить g_strdup_printf().

g_strdup_printf()

Аналогично стандартной функции C sprintf(), но более безопасна, поскольку она вычисляет максимальное требуемое пространство и выделяет память для хранения результата. Возвращенная строка должна быть освобождается с помощью g_free(), когда больше не требуется.

Добавьте к этому острые ощущения, делающие огромное количество строковых изменений в коде, чтобы делать "полезные" вещи, такие как смена gchar на char, gint на int, gboolean на bool и т.д. и т.д., ad nauseam до моего Сравнение субверсии теперь представляет собой телефонную книгу. Хуже того, вам в конечном итоге приходится менять все больше и больше кода, потому что этот материал засоряется по всем файлам .h, поэтому он постоянно расширяется, как волнованный труп, в огромный беспорядок.

Если вы просматриваете контрактную работу и смотрите в glib.h в любом месте, RUN!!! Просто скажи НЕТ!

PS: Загружая исходный код, удаляя все типы, относящиеся к Gnome, и перекомпилируйте его, чтобы создать свои собственные функции "g _", а не сортировать, работать как угодно, и это большая экономия времени.

Иллюстрация B: g_strdup_printf()

Больше ужасающего гнома с крапполой от Гнома. У 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;
}

Функция ANY printf() не только медленнее, чем snot при абсолютном нуле, вы заметите, что они выделяют для хранения весь байт, yup, целый gchar c, что гарантирует переполнение, но тогда кто заботится? они получат длину строки, которая им понадобится для malloc() - потому что они собираются развернуться и снова выполнить весь printf() - на этот раз "волшебным образом" с достаточным объемом памяти.

Они добавят +1 к размеру, конечно, так что у вас будет место для нулевого терминатора, гарантированного, с ужасным расходом, конечно, но они спрятали его настолько глубоко в коде, который они делая ставки, вы просто сдаетесь и будете использовать его вслепую и не заметите, какой массивный мозговой пупок. Спасибо, ребята. Мне просто нравится мой код, чтобы ползать.

Не позволяйте функции _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.

Ответ 7

Вот обновление. Похоже, разработчик осознал свою ошибку:

g_mem_is_system_malloc устарел с версии 2.46 и не должен использоваться во вновь написанном коде.

GLib всегда использует системный malloc, поэтому эта функция всегда возвращает TRUE.

Проверяет, является ли распределитель, используемый g_malloc(), реализацией системы malloc. Если он возвращает TRUE память, выделенную с помощью malloc(), можно использовать взаимозаменяемую с памятью, выделенной с помощью g_malloc(). Эта функция полезна для исключения дополнительной копии выделенной памяти, возвращенной API-интерфейсом, отличным от GLib.

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