Я использую атрибут переменной очистки для освобождения мьютекса с помощью этого макроса [...]
Не могу сказать, что высоко оцениваю эту идею. Это делает ваш код загадочным для любого, кто его читает (возможно, даже для вас в будущем), и рискует вызвать неопределенное поведение в случае, если переменная прокси выходит из области видимости иным способом, чем вы ожидаете, так что, возможно, мьютекс уже (или все еще) разблокирован или, возможно, даже не инициализирован.
Не говоря уже о том, что использование языковых расширений, особенно таких уникальных c, как атрибуты G CC, очень тесно связывает вас с конкретной реализацией C. Возможно, вас это не волнует, но если это я, я, по крайней мере, хочу получить что-то очень ценное взамен, и я не вижу этого здесь.
Узнав о составных литералах, Я хотел избавиться от переменной tmpv_
, так как она не нужна в этом контексте.
Но это необходимо , или, по крайней мере, что-то нужно, чтобы повесить атрибут на. Я предполагаю, что вы пытаетесь повесить атрибут на составном литерале, но G CC не документирует эту поддержку:
Ключевое слово __attribute__
позволяет вам задавать специальные свойства переменных, параметры функции или структура, объединение и, в C ++, члены класса. [...] Другие атрибуты доступны для функций (см. Атрибуты функций), меток (см. Атрибуты меток), перечислителей (см. Атрибуты перечислителей), операторов (см. Атрибуты операторов) и для типов (см. Атрибуты типов).
( G CC электронная документация )
Составной литерал не является ни одним из элементов, документированных для поддержки атрибутов G CC.
Вы продолжаете,
#define LOCK() \
pthread_mutex_lock(&mutex); \
(void)(int32_t __attribute__((cleanup(mutexUnlock)))){0}
Но компилятор выдает мне предупреждение для каждого места, где используется макрос:
warning: 'cleanup' attribute does not apply to types [-Wattributes]
Я не уверен, как это интерпретировать.
Единственная конструкция syntacti c в этом коде, к которой предположительно может быть прикреплен атрибут, - это имя типа int32_t
. Как предупреждает G CC, атрибут cleanup
не применяется к типам (хотя есть и другие атрибуты, которые применяются к типам). В результате использование атрибута не будет иметь никакого эффекта, как вы уже заметили (еще одна причина, чтобы не пытаться быть милым / волшебным). G CC решает предупредить вас об этой проблеме, вместо того, чтобы либо вообще прекратить компиляцию, либо игнорировать атрибут без уведомления.
В чем проблема с этим кодом?
Если Вы можете прикрепить атрибуты к составным литералам, я ожидаю, что G CC потребует, чтобы они предшествовали или следовали за литералом, а не появлялись внутри него. Но опять же, насколько я могу судить, G CC не поддерживает атрибуты для составных литералов.
В общем, единственный удаленно разумный способ использовать атрибут __cleanup__
- это прикрепить его к объекту. Вы хотите очистить - mutex
в этом случае. Присоединение его к прокси-объекту с целью использования области действия этого объекта для запуска случайного поведения, связанного с другим объектом, является печальным злоупотреблением этой функцией. Я бы порекомендовал отказаться от всей идеи и вместо этого явно разблокировать мьютекс.