Что это за синтаксис функции C?

Я бы сказал, что у меня есть средний опыт программирования на c, однако я никогда раньше не видел, чтобы этот синтаксис использовался для создания функции. Это напоминает мне синтаксис события JQuery. В целом, я хотел бы получить подробное объяснение того, что это такое и каким может быть альтернативный синтаксис. Ссылка на то, где я мог бы прочитать больше об этом, в частности, тоже была бы отличной.

 // Set handlers to manage the elements inside the Window
 window_set_window_handlers(s_main_window, (WindowHandlers) {
    .load = main_window_load,
    .unload = main_window_unload
  });

Это фрагмент кода из учебника по Pebble WatchApp.


person lavacode    schedule 11.08.2016    source источник
comment
Я думаю, что это создание структуры, приведение к WindowHandlers и передача ее в эту функцию.   -  person Alex    schedule 12.08.2016
comment
@Alex - Нет, это составной литерал. Кстати, это вызов функции AFAIK. Никакая функция не создается, но вместо этого вызывается одна. Второй аргумент функции является составным литералом.   -  person AnArrayOfFunctions    schedule 12.08.2016
comment
window_set_window_handlers имеют 2 параметра s_main_window и структуру WindowHandlers, здесь инициализируется структура WindowHandlers   -  person fedi    schedule 12.08.2016
comment
@CisNOTthatGOODbutISOisTHATBAD Я плохо выразился. Это в основном то, что я имел в виду. Я проводил параллели со списками инициализации C++, но не знал, как это называется.   -  person Alex    schedule 12.08.2016
comment
@Alex: в составном литерале нет приведения. Актерский состав — это совсем другой зверь.   -  person too honest for this site    schedule 12.08.2016
comment
@ Олаф Спасибо, я буду иметь это в виду. Опять же, я ничего не знал о составных литералах. Это выглядело как смесь списка инициализации и приведения. Я понял, что это дало WindowHandler. Это единственное, в чем я был уверен. Когда я написал, что был состав, это было скорее нечетко, что я рассеянно добавил, когда строил дальнейшие догадки. Не предназначен для серьезного отношения   -  person Alex    schedule 12.08.2016
comment
@BruceDavidWilner: Хватит ОРАТЬ! И учите Си, это есть Си - и очень строго!   -  person too honest for this site    schedule 12.08.2016


Ответы (2)


Это вызов функции, использующий составной литерал. Это эквивалентно следующему:

WindowHandlers temp = {
    .load = main_window_load,
    .unload = main_window_unload
  };
window_set_window_handlers(s_main_window, temp );

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

Предполагая, что WindowHandlers содержит только load и unload в таком порядке, приведенное выше эквивалентно:

WindowHandlers temp = { main_window_load, main_window_unload };
window_set_window_handlers(s_main_window, temp );

стандарт C описывает это более подробно. .

Из раздела 6.5.2.5:

4 Постфиксное выражение, состоящее из имени типа в скобках, за которым следует заключенный в фигурные скобки список инициализаторов, является составным литералом. Он предоставляет безымянный объект, значение которого задается списком инициализаторов.

...

9 ПРИМЕР 1. Определение области действия файла

int *p = (int []){2, 4};

инициализирует p так, чтобы он указывал на первый элемент массива из двух целых чисел, первый из которых имеет значение два, а второй — четыре. Выражения в этом составном литерале должны быть постоянными. Безымянный объект имеет статическую продолжительность хранения.

Из раздела 6.7.8:

1

initializer:
    assignment-expression
    { initializer-list }
    { initializer-list , }
initializer-list:
    designationopt initializer
    initializer-list , designationopt initializer
designation:
    designator-list =
designator-list:
    designator 
    designator-list  designator
designator:
    [ constant-expression ]
    .identifier

...

7 Если обозначение имеет форму

.identifier

тогда текущий объект (определенный ниже) должен иметь тип структуры или объединения, а идентификатор должен быть именем члена этого типа.

...

34 ПРИМЕР 10 Члены структуры могут быть инициализированы ненулевыми значениями независимо от их порядка:

div_t answer = { .quot = 2, .rem = -1 };
person dbush    schedule 11.08.2016
comment
Не могли бы вы объяснить, что означают ведущие точки для переменных? - person user1717828; 12.08.2016
comment
@user1717828 user1717828 Они указывают, какие поля в инициализируемой структуре должны быть установлены. - person dbush; 12.08.2016

Это стандарт, начиная с C99. Он объединяет составные литералы:

(WindowHandlers) {}

и назначенные инициализаторы:

.load = main_window_load,
.unload = main_window_unload

См. ссылку Что означает этот точечный синтаксис в руководстве по разработке часов Pebble?

person Osama Ashaikh    schedule 11.08.2016
comment
Что ж, это стандартный язык C, введенный в C99 (но все еще действующий). - person too honest for this site; 12.08.2016