LINUX.ORG.RU

g_list_foreach и прочие - насколько безопасно?


0

0

Добрый день.

Возник вот такой вопрос. В примерах для GTK очень часто используется следующая конструкция:
g_list_foreach(list, gtk_tree_path_free, NULL);

Интересует, собственно, вот что: функция gtk_tree_path_free принимает всего один аргумент, но g_list_foreach передает ей два (GtkTreePath и NULL). Я очень далек от ассемблера, но мне кажется, что я где-то слышал, что (как минимум) на Intel совместимых архитектурах переменные для функции в стек складывает вызывающая функция и после выполнения вызываемой функции она же их от туда извлекает. В таком случае все должно работать нормально, но вот как обстоят дела на других архитектурах? Насколько "правильно" подобное использование g_list_foreach?

anonymous

> что (как минимум) на Intel совместимых архитектурах переменные для функции в стек складывает вызывающая функция

чего? при чём здесь архитектура?

Joe_Bishop
()

void g_list_foreach(GList *list, GFunc func, gpointer user_data);

void (*GFunc) (gpointer data, gpointer user_data);

функция, передаваемая вторым параметром в g_list_foreach, ДОЛЖНА принимать два значения. 

Legioner ★★★★★
()

> что (как минимум) на Intel совместимых архитектурах переменные для функции в стек складывает вызывающая функция

отсыпь, а? :)

Deleted
()
Ответ на: комментарий от Joe_Bishop

> чего? при чём здесь архитектура?

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

ShprotX
()
Ответ на: комментарий от Legioner

> функция, передаваемая вторым параметром в g_list_foreach, ДОЛЖНА принимать два значения

Вследствие особенности вызова функции в C, она должна принимать не более двух значений.

ShprotX
()
Ответ на: комментарий от Legioner

> И какие есть особенности вызова функций в С?

Первый аргумент ложится в стэк последним и извлекается первым. Таким образом, независимо от того, будет ли функции передано 1 или 20 аргументов, первый аргумент всегда будет в 4(%esp), второй - в 8(%esp) и т.д.

ShprotX
()
Ответ на: комментарий от ShprotX

> Первый аргумент ложится в стэк последним и извлекается первым.

А иногда наоборот. А иногда аргументы через регистры передаются. А иногда первые три аргумента через регистры, а остальные через стек. Это называется calling conventions, и конкретно к С отношения не имеют.

Legioner ★★★★★
()
Ответ на: комментарий от dilmah

Почему? В стандарте чётко написано, что порядок вычисления аргументов не определён и при любых попытках передачи неправильного числа/типа аргументов поведение не определено.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

в том же стандарте написано что преобразовывать указатели на функции с разными аргументами нельзя.

> Почему?

ну не будут функции с переменным числом аргументов (декларированными через ...) работать если аргументы класть в стек не с конца.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

> ну не будут функции с переменным числом аргументов (декларированными через ...) работать если аргументы класть в стек не с конца.

Ну в принципе да, но никто не мешает для функций с переменным числом параметров (которые используются не очень часто) и для функций с фиксированным числом параметров использовать разные соглашения о вызовах.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

> Ну в принципе да, но никто не мешает для функций с переменным числом параметров (которые используются не очень часто) и для функций с фиксированным числом параметров использовать разные соглашения о вызовах

Насколько я понимаю, это неписаный стандарт для компиляторов C.

ShprotX
()
Ответ на: комментарий от ShprotX

Очень даже "писанный", гугли ABI.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.