Каковы предостережения от приведения g_free к GWeakNotify? - PullRequest
2 голосов
/ 09 марта 2012

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

Я написал простую программу для проверки приведениявсе выглядит нормально - то есть второй параметр «пропускает»:

#include <stdlib.h>
#include <stdio.h>

#include <gtk/gtk.h>

void
callFree(GWeakNotify notify, gpointer pData, GObject *pObject)
{
  notify(pData, pObject);
}

int
main(int argc, char **argv)
{
  (void)argc;
  (void)argv;

  gpointer pData = g_malloc(32);
  GObject *pNull = (GObject *)g_malloc(64);  //results in a 64B leak

  if (!pData)
  {
    fprintf(stdout, "Unable to allocate pdata\n");
  }
  else
  {
    fprintf(stdout, "pData allocated OK...freeing\n");

    callFree((GWeakNotify)g_free, pData, pNull);
  }

  return EXIT_SUCCESS;
}

Мои вопросы: 1) Что происходит за кулисами?Второй аргумент просто оставлен в стеке, и g_free не заботится об этом (поскольку он не должен)?

2) Почему компилятор не жалуется на это, учитывая две подписи (1 параметр для g_freeи два для GWeakNotify)?

Спасибо!P

1 Ответ

2 голосов
/ 09 марта 2012

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

Компилятор не жалуется на это именно из-за приведения GWeakNotify; в основном вы говорите: «Не жалуйтесь, что эти функции имеют разные подписи». Если вы опустите актерский состав, он будет жаловаться.

(Обратите внимание, что pData никогда не будет NULL в вашем коде; g_malloc() прерывает программу, если она не может выделить запрошенную память. Если вы хотите другое поведение, используйте g_try_malloc() или обычный malloc().)

...