scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 00:57
Оценка:
Hello...

I want to discuss the possibility of the implementation of some
programming technique, which allows to use synchronization primitives,
especially mutexes, seamlessly, like this can be done in C++ with
std::lock_guard.

The idea is that manual operating on mutex is inconvenient and error
prone, so it was be desirable to have some blocks of code which executed
with specified mutex locked, but at same time where shold be no
necessity to manually lock and especially to unlock the mutex (which can be
forgotten). And of course, in case if code block is leaved by some sort
of "goto" operators (break, continue, return), mutex still must be
unlocked automatically.

Basically desired syntax must have the form:

    // mutex isn't locked here
    ...
    {
        DECLARE_SCOPED_LOCK(mutex);   // mutex locked now

        perform operations with mutex locked...

        if (condition)
           break/continue/return/goto...

    }  // mutes unlocked here


Or the following form might be acceptable too:
    DECLARE_SCOPED_LOCK(mutex);  // mutex locked now
    {
       perform operations with locked mutex...

       if (condition)
          break/continue/return/goto...

    }  // mutex unlocked here


First, as I understood, there is no way to avoid of "gotos" from
any point in code to any other point. And using of "goto" violates
principles of structure programming, moving us to fortran-like spaghetty.
So we assume, that "goto" operator must have limited usage.

Second, is the question how to execute function which unlocks the mutex
at end of the block. The only way which C language allows, as I think,
is the use of "for" operator, like this:
    for (mutex_lock(&mutex); one-time-condition; mutex_unlock(&mutex))
    {
       operations with locked mutex...
    }


"one-time-condition" here is any condition which assures, that loop
body executes exactly one time. In this case "break" and "continue"
operators work as expected (allows to break the loop and unlock
mutex on the exit).

The "return" operator is the problem. It can appear almost in any place
and just silently finishes the function. And comparing with "goto" it is
really dangerrous. If "goto", as said above, must have limited usage,
"return" operator might be met anythere in the code.

One possible solution is to redefine "return" with macroprocessor,
and substitute it with some other operator. But such approach arises
another problem, that "return" might be used in very different contexts
and such substitution will be inapropriate (and even dangerrous) in
other contexts. Substitution must not break other code.

I have found possible solution, which allows to stop compilation,
if "return" meets in the block of code related to scoped lock,
and which have no any effects at all in other contexts. The idea
is that "return" operator might be defined like this:
    #define return   return (void)sizeof((some_type*)some_var),


And in same header file, where "return" operation redefined, variable
"some_var" (of type "some_type*") and the type "some_type" must be declared.

Left part of comma operator have no any effect on return value (which is
right part of comma operator). Moreover, left part even not generates
any runtime code, it is evaluated solely in compile time. So such
substitution of "return" operator doesn't pose any danger any other code.

But in context of scoped lock, the variable "some_var" might be defined
with other type (so it shadows file scoped variable). And this gives an
error in case if "return" operator meets in the body of scoped lock,
because the types (in the arguments of sizeof operator) are different and
not compatible now.

So, now we have a method to prevent use "return" operator in the block
of code related to scoped lock. And this gives us guarantee, that lock
always will be unlocked (except of cases, when code uses "goto" or
"longjmp", which is not typical cases).

But if programmer still wants to return from the function now, but not
finish all multiple nested scoped locks, we can provide special macros
for this, which can be used in place of "return" operator for scoped
locks. This is not hard, and you will see it in full example below.

So, it's time to unveil complete solution -- see below.

I requesting for your comments, improvements, critics, suggestions.


#include <stdio.h>
#include <stddef.h>

/* Mutex object imitation, just for example. */
struct mutex {
    int v;
};

void mutex_lock(struct mutex *m)
{
    (void)m;
    printf("mutex %p locked\n", (void*)m);
}

void mutex_unlock(struct mutex *m)
{
    (void)m;
    printf("mutex %p unlocked\n", (void*)m);
}

/* This variable must exist in global namespace to implement "return" macros (see below).
 * This definition must be placed in some header file to be available at file scope level. */
static const struct _can_return { int dummy; } *_can_return;

/* Avoid warning about unused "_can_return" symbol. */
struct _can_return_unused { int dummy[sizeof(_can_return)]; };

/* Linked list of all locked mutexes in SCOPED_LOCKs within single function. */
struct _scope {
    const struct _scope *next;
    struct mutex *mutex;
};

/* Last element within linked list shown above (must exist and file scope level.
 * This definition must be placed in some header file to be available at file scope level. */
static const struct _scope *const _scope = NULL;

/* avoid warning about unused "_scope" symbol */
struct _scope_unused { int dummy[sizeof(_scope)]; };

/* This macros declares, that following operator (or operators block) will
 * be executed with locked specified mutex, which will be unlocked automaticaly
 * on leaving following operator or block (see example below). */
#define SCOPED_LOCK(MutexPtr) \
    for (struct _scope _this_scope = {_scope, (mutex_lock(MutexPtr), MutexPtr)}, *_scope = &_this_scope; \
            _scope->mutex != NULL;                                                                       \
            mutex_unlock(_scope->mutex), _scope->mutex = NULL)                                           \
    for (struct { int i; } _can_return = {0}; !_can_return.i; _can_return.i = 1)


/* This macros prevents using of "return" operator in the in the block followoing
 * SCOPED_LOCK keyword. In this case compilation finished with an error
 * (due to incompatible types). In other contexts "return" operator works as usual
 * and this modification (left part of comma operator) have no effect. The idea is
 * that in SCOPED_LOCK context and at file scope "_can_return" symbol have different
 * types, and type of "_can_return" symbol in SCOPED_LOCK context causes compilation
 * error. */
#define return  return (void)sizeof((struct _can_return *)_can_return),

/* This macros might be used in code block following SCOPED_LOCK as alternative to
 * "return" operator. It allows to return from all nested scoped locks and unlock
 * all previously locked mutexes. Where is no problem if this macros
 * will be used outside of SCOPED_LOCK -- this not causes an error. */
#define SCOPE_RETURN(val)                                       \
    do {                                                        \
        const struct _scope *scope = _scope;                    \
        while (scope && scope->mutex)                           \
            mutex_unlock(scope->mutex), scope = scope->next;    \
        struct _can_return *_can_return = NULL;                 \
        return (val);                                           \
    } while(0);
    

/* This example shows how SCOPED_LOCK macros can be used. */
int main()
{
    struct mutex m1 = {0};
    struct mutex m2 = {1};
    
    SCOPED_LOCK(&m1)
    {
        SCOPED_LOCK(&m2)
        {
            if (0) {
                break;  // "break" operator allows to exit from inner SCOPED_LOCK
            }
        
            if (0) {
                // return 1;    // this gives compilation error
                SCOPE_RETURN(2);
            }
        }
    }
    
    SCOPE_RETURN(3);

    return 0;
}
Re: scoped lock in plain C (similar to
От: Vamp Россия  
Дата: 13.12.21 03:00
Оценка:
Во-первых, отмечу что язык форума — русский.

Во-вторых, с какой целью все это было затеяно? Если с академической, то где-то даже интересно. Если с практической, то неработоспособно, а главное, бессмысленно. В С++ все это было сделано именно потому, что в С этого нет.
Да здравствует мыло душистое и веревка пушистая.
Re: scoped lock in plain C (similar to
От: kov_serg Россия  
Дата: 13.12.21 05:02
Оценка: +6 :)
Здравствуйте, fk0, Вы писали:

fk0> I want to discuss the possibility of the implementation of some

fk0>programming technique, which allows to use synchronization primitives,
fk0>especially mutexes, seamlessly, like this can be done in C++ with
fk0>std::lock_guard.

#define return  return (void)sizeof((struct _can_return *)_can_return),
За такое сразу бить ногами
Re: scoped lock in plain C (similar to
От: Mr.Delphist  
Дата: 13.12.21 08:37
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> I want to discuss the possibility of the implementation of some

fk0>programming technique, which allows to use synchronization primitives,
fk0>especially mutexes, seamlessly, like this can be done in C++ with
fk0>std::lock_guard.

Кто с ENG-ом к нам придёт — от него и получит:
https://windowsasusual.blogspot.com/2012/06/plain-c-with-raii-idiom.html
Re[2]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 12:35
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Во-первых, отмечу что язык форума — русский.


V>Во-вторых, с какой целью все это было затеяно? Если с академической, то где-то даже интересно. Если с практической, то неработоспособно,


В каком-то смысле и с академической, т.к. других решений мне не известно на сегодняшний момент.

Вполне работоспособно: https://coliru.stacked-crooked.com/a/1711230a410131da

Соответствует стандарту, и должно работать на всех компиляторах тоже соответствующих стандарту.

V> а главное, бессмысленно. В С++ все это было сделано именно потому, что в С этого нет.


Бессмысленно для чего? Для C++ это всё не нужно. Речь про plain C, где нет концепции RAII,
но хочется в каком-то виде иметь её преимущества.
Re[2]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 12:37
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, fk0, Вы писали:


#define return  return (void)sizeof((struct _can_return *)_can_return),


_> За такое сразу бить ногами


Я специально подчеркнул, что такое изменение никак не затрагивает другой код, т.к. sizeof()
в runtime никак не проникает и существует только в compile time.
Re[3]: scoped lock in plain C (similar to
От: Alexander G Украина  
Дата: 13.12.21 12:44
Оценка:
Здравствуйте, fk0, Вы писали:

_>> За такое сразу бить ногами


fk0> Я специально подчеркнул, что такое изменение никак не затрагивает другой код, т.к. sizeof()

fk0>в runtime никак не проникает и существует только в compile time.

Переопределение ключевого слова — UB.
Русский военный корабль идёт ко дну!
Re[3]: scoped lock in plain C (similar to
От: Vamp Россия  
Дата: 13.12.21 13:34
Оценка: +1
fk0> Вполне работоспособно: https://coliru.stacked-crooked.com/a/1711230a410131da

fk0> Соответствует стандарту, и должно работать на всех компиляторах тоже соответствующих стандарту.


Нарушает многие идиомы С. Требует писать код в строгом соответствии с твоими предложениями, которые весьма ограничивают (например, ты запретил goto и сломал longjmp, а в С он используется, например, для структурной обработки ошибок)

V>> а главное, бессмысленно. В С++ все это было сделано именно потому, что в С этого нет.


fk0> Бессмысленно для чего? Для C++ это всё не нужно. Речь про plain C, где нет концепции RAII,

fk0>но хочется в каком-то виде иметь её преимущества.
А зачем? C++ уже есть. Хочешь функционала С++ — используй С++.
Да здравствует мыло душистое и веревка пушистая.
Re: scoped lock in plain C (similar to
От: reversecode google
Дата: 13.12.21 13:49
Оценка:
С уже почил
ну кроме тех мест где торвальдс еще имеет право на мерж в свое ядро
а так везде уже С++
я на нём еще в году так 2006 в ядре использовал для raii итд
Re[4]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 14:16
Оценка:
Здравствуйте, Vamp, Вы писали:


fk0>> Вполне работоспособно: https://coliru.stacked-crooked.com/a/1711230a410131da


fk0>> Соответствует стандарту, и должно работать на всех компиляторах тоже соответствующих стандарту.


V>Нарушает многие идиомы С. Требует писать код в строгом соответствии с твоими предложениями, которые весьма ограничивают (например, ты запретил goto и сломал longjmp, а в С он используется, например, для структурной обработки ошибок)


В данном случае, если то же самое написать руками, goto и longjmp использовать тоже нельзя:

    mutex_lock(&mutex);
        {
        if (cond)    
        goto label;

        if (cond)
        longjmp(jmpbuf, 1);

        }
    mutex_unlock(&mutex);

label:


В обоих случаях выходы из блока кода -- фатальная ошибка. И было б лучше, если бы
её было допустить сложно. Вся идея в этом. Если код писать руками как есть, то высок
шанс допустить ошибку, возрастает объём кода, снижается читаемость и т.п.
Идея ввести scoped lock и заключается в том, чтобы упростить программирование и уменьшить ошибки.


V>>> а главное, бессмысленно. В С++ все это было сделано именно потому, что в С этого нет.


fk0>> Бессмысленно для чего? Для C++ это всё не нужно. Речь про plain C, где нет концепции RAII,

fk0>>но хочется в каком-то виде иметь её преимущества.
V>А зачем? C++ уже есть. Хочешь функционала С++ — используй С++.

Есть достаточно широкий ряд причин, когда C++ использовать нельзя:

1) legacy-код, где изначально был выбран язык C и переход на C++ осуществить практически очень
сложно (существует два десятка пунктов по которым C и C++-код не совместимы, ряд этих пунктов
широко используется в C-коде и требуется ввиду чего существенный рефакторинг);

2) для целевой платформы нет C++-компилятора (что вполне возможно в embedded);

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

4) как ни странно -- не соответствующая квалификация привлечённых к проекту работников
не позволяющая безопасно использовать C++ (а привлекаемые C++-программисты наоборот,
могут не обладать квалификацией в других областях).
Re[4]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 14:17
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, fk0, Вы писали:


_>>> За такое сразу бить ногами


fk0>> Я специально подчеркнул, что такое изменение никак не затрагивает другой код, т.к. sizeof()

fk0>>в runtime никак не проникает и существует только в compile time.

AG>Переопределение ключевого слова — UB.


Где об этом сказано? Аргументируй. Я думаю, что нигде и это очень сомнительное мнение.
Фазы препроцессинга и компиляции вообще классически выполняются разными программами и
как препроцессор ничего не знает о ключевых словах, так и компилятор не знает, что оно
было "переопределено".
Re[5]: scoped lock in plain C (similar to
От: kov_serg Россия  
Дата: 13.12.21 14:43
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Где об этом сказано? Аргументируй. Я думаю, что нигде и это очень сомнительное мнение.

fk0>Фазы препроцессинга и компиляции вообще классически выполняются разными программами и
fk0>как препроцессор ничего не знает о ключевых словах, так и компилятор не знает, что оно
fk0>было "переопределено".
Проблемы будут когда таких изобретателя соберутся в одной точке.
C это не про удобство и комфорт это больше похоже на танцы на минном поле, надо быть внимательным и не забывать где мины (в том числе и те что сам раставал)
Зато в теле такая гибкость появляется
Re[6]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 15:26
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, fk0, Вы писали:


fk0>> Где об этом сказано? Аргументируй. Я думаю, что нигде и это очень сомнительное мнение.

fk0>>Фазы препроцессинга и компиляции вообще классически выполняются разными программами и
fk0>>как препроцессор ничего не знает о ключевых словах, так и компилятор не знает, что оно
fk0>>было "переопределено".
_>Проблемы будут когда таких изобретателя соберутся в одной точке.

Это не аргументация. В C, где нет понятия namespace, конфликтовать может
что угодно с чем угодно, т.к. все сидят в общем пространстве имён и символов,
и типов. Ничего нового такое изменение не привносит.

Единственная проблема, использование ключевого слова return в метапрограммировании
на макросах, например: http://coliru.stacked-crooked.com/a/59db7bdc3e2181b0

Я думаю, что если люди занимающимися такими вещами сталкиваются с проблемой, они умеют
эту проблему решать, это в целом не проблема а попросту конфликт имён.
Re[5]: scoped lock in plain C (similar to
От: Vamp Россия  
Дата: 13.12.21 15:37
Оценка:
fk0> В данном случае, если то же самое написать руками, goto и longjmp использовать тоже нельзя:
Если писать руками, то это идиоматичный код, с которым люди знакомы.

fk0> 1) legacy-код, где изначально был выбран язык C и переход на C++ осуществить практически очень

fk0> сложно (существует два десятка пунктов по которым C и C++-код не совместимы, ряд этих пунктов
fk0> широко используется в C-коде и требуется ввиду чего существенный рефакторинг);
Во всех компиляторах, которыми я пользуюсь, есть режим совместимости с С. Приведи пример кода на С, не поддерживаемого gcc.

fk0> 2) для целевой платформы нет C++-компилятора (что вполне возможно в embedded);

Не знаю, где такие остались. Если где-то остались — проще прогнать через CFront , чем городить твой велосипед.


fk0> 3) системное программирование (в противовес прикладному), где использование C++ сталкивается

fk0> с рядом специфических ограничений: хотя я и не отрицаю, что при этом возможно, но решение
fk0> возникающих сложностей требует значительного отвлечения ресурсов.
Кроме ядер, я не знаю, где такие ограничения остались. Но из ядер тебя с таким кодом прогонят все равно

fk0> 4) как ни странно -- не соответствующая квалификация привлечённых к проекту работников

fk0> не позволяющая безопасно использовать C++ (а привлекаемые C++-программисты наоборот,
fk0> могут не обладать квалификацией в других областях).
Уж людям с недостаточной квалификацией С точно опаснее, чем С++.
Да здравствует мыло душистое и веревка пушистая.
Re[5]: scoped lock in plain C (similar to
От: Vamp Россия  
Дата: 13.12.21 15:46
Оценка:
.

AG>>Переопределение ключевого слова — UB.


fk0> Где об этом сказано?

Ну в 6.4.1, например.
Да здравствует мыло душистое и веревка пушистая.
Re[6]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 15:54
Оценка:
Здравствуйте, Vamp, Вы писали:

AG>>>Переопределение ключевого слова — UB.


fk0>> Где об этом сказано?

V>Ну в 6.4.1, например.

Там ничего не говориться о препроцессоре. Там просто приведён список зарезервированных
идентификаторов в пространстве имён компилятора (едином для типов, функций, переменных),
и что типп/функцию/переменную с таким именем завести не получится. К препроцессору-то
какое это имеет отношение?

Вот ссылка на драфт полной версии действующего стандарта:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf

Прошу указать конкретное место, где говорится об undefined behaviour.
Я такого не вижу.
Re[6]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 13.12.21 16:18
Оценка:
Здравствуйте, Vamp, Вы писали:



fk0>> В данном случае, если то же самое написать руками, goto и longjmp использовать тоже нельзя:

V>Если писать руками, то это идиоматичный код, с которым люди знакомы.

fk0>> 1) legacy-код, где изначально был выбран язык C и переход на C++ осуществить практически очень

fk0>> сложно (существует два десятка пунктов по которым C и C++-код не совместимы, ряд этих пунктов
fk0>> широко используется в C-коде и требуется ввиду чего существенный рефакторинг);

V>Во всех компиляторах, которыми я пользуюсь, есть режим совместимости с С. Приведи пример кода на С, не поддерживаемого gcc.


Это только недавно обсуждали в соседней ветке:
https://rsdn.org/forum/flame.comp/8113649.1
Автор: fk0
Дата: 16.10.21


Часть из перечисленного никак с C++ не совместимо (на основе реального проекта):

1) конфликт из-за большего списка зарезервированных в C++ слов (вроде private, public, class, auto, new)
и наоборот проблема с отсутствующим restrict (тривиально решаемая).

2) C++ требует чтоб литерали всегда разделялись пробелами ("xxx"YYY"zzz" -> "xxx" YYY "zzz");

3) проблема с char* и const char* (в C строковый литерал -- char*).

4) типы продекларированные в декларации других типов в C попадают в общее пространство имён,
а не остаются внутри типа как в C++ (это заставляет переделывать такие C-декларации в
"нормальную" форму для C++);

5) в C++ тип void* требует ручного приведения к любому другому типу: это реально проблема,
т.к. нужны изменения в каждой десятой строчке кода, условно, в ряде специфических для
C-проекта макросов и т.п.

6) flexible array members отсутствуют в C++ (и особенно их инициализация, что не поддерживается
никакими компиляторами C++);

7) адресная арифметика над void*;

8) проблемы с варнингом -Wc++11-narrowing (в C его нет...);

9) не совсместимость enum'ов разных типов в C++ (что конечно хорошо, но код переделывать);

10) Tentative definitions в C++ не поддерживаются, т.е. из-за этого в принципе невозможно
forwarddeclaration для статических переменных (но можно для функций -- переделывать код);

11) определения типов в декларации функции, прямо в списке её аргументов, в C++ так нельзя;

12) совершенно шикарная в разных разрезах проблема с compound literals: если даже C++ их
и поддерживает, то они существуют только как temporary objects, а в C могут сущетвовать
статически (что ведёт к глюкодрому), кроме того в C99 и C11 есть разница в определении
срока жизни compound literal (в одном случае до sequence point, в другом до конца
full expression, до точки с запятой), что тоже глюкодром;

13) в C++ все const переменные по-умолчанию становятся static, и без изменений код не слинкуется;

14) в C++ все const переменные нужно обязательно инициализировать (см. также пункт 10);

15) все inline функции нужно сделать static inline, и здесь тоже морока с разным пониманием
inline в разных режимах (стандарта языка) и разными компиляторами: в C++ и по стандарту
static inline это понятно что, а у GNU ещё есть свой inline, который link once, как
шаблонные функции в C++...

16) struct, union, enum все эти слова в C++ определяют новый тип и могут вызывать конфликты имён,
в C возможно сделать struct NAME {...}; и потом typedef other-type NAME. В C++ это проблема.

17) в C++ неовмозможно с помощью goto перепрыгнуть через неинициализированную переменную,
реальная C-программа написана настоящими программистами, разумеется, которые используют
фортран (отсылаю к известному юмористическому тексту) и не приемлют так называемое
структурное программирование которое для сосунков -- и это проблема в C++;

18) минорная проблема: декларация функций в C вида int func(int x, char arr1[static 42], int arr2[func(x)])
(ни static, ни вызов функций в декларации размера массива в C++ не поддерживается);

19) минорная проблема: декларации в стиле K&R.


fk0>> 2) для целевой платформы нет C++-компилятора (что вполне возможно в embedded);

V>Не знаю, где такие остались. Если где-то остались — проще прогнать через CFront , чем городить твой велосипед.

Я полностью согласен с этим мнением, что разработка нового ПО на C в большей части, случаев,
да почти во всех -- идиотизм. Язык C++ создавался для того, чтобы усовершенствовать язык C
и исправить явные имеющиеся недостатки. На C++ можно всё сделать то же самое, что и на C,
только лучше (но нужна выше квалификация). Если что-то в C++ мешает, то можно просто не
использовать. Хотя исключения всяко лучше чем longjmp, RTTI предоставляемый компилятором
(и бесплатный) лучше, чем то же самое, но самодельное, виртуальные функции предоставляемые
компилятором, лучше чем таблицы коллбэков созданные вручную и т.д. и т.п. Глупо отрицать,
что C++ сообщество за последние 30 лет достригло большого прогресса...

Но имеем что имеем. Потому и.


fk0>> 3) системное программирование (в противовес прикладному), где использование C++ сталкивается

fk0>> с рядом специфических ограничений: хотя я и не отрицаю, что при этом возможно, но решение
fk0>> возникающих сложностей требует значительного отвлечения ресурсов.
V>Кроме ядер, я не знаю, где такие ограничения остались. Но из ядер тебя с таким кодом прогонят все равно

Я не вижу препятствий для ядер в C++. Fuchsia от Google, как пример.
Re: scoped lock in plain C (similar to
От: no_ise  
Дата: 13.12.21 16:21
Оценка: 4 (1)
Здравствуйте, fk0, Вы писали:

fk0>Hello...


fk0> I want to discuss the possibility of the implementation of some

fk0>programming technique, which allows to use synchronization primitives,
fk0>especially mutexes, seamlessly, like this can be done in C++ with
fk0>std::lock_guard.


Ну ясно, думал над этим когда-то, но хорошего решения не нашел. Хотя приходилось профессионально
использовать С для реализации алгоритмов в проприетарных библиотеках.

Т.к. новадейз plain C используется не для мейнстрима где стандарты качества всего-лишь усредненные,
а например для вещей где кода хоть и не очень много, но требуется чтобы компилировалось и работало
без всяких 'но' на всяких современных и не очень платформах, то я понимаю под хорошим решением:

1) Должно соответствовать стандарту ANSI C или какому-либо еще стандарту С, без всяких хаков и использования особенностей компилятора.

2) Не должно запарывать оптимизацию компилятору, во всяком случае для типовых случаев.

3) Собственно синтаксис должен быть не особо извращенским для типовых случаев.

4) Если goto и longjmp не считать типовыми случаями, то для них должен быть как минимум извращенский воркараунд.


Для меня тема не настолько актуальная, чтобы ей заниматься, но если кто-либо опубликует хорошее решение, то это прям
весело будет!
Re: scoped lock in plain C (similar to
От: Cyberax Марс  
Дата: 13.12.21 23:50
Оценка: 23 (3) +1
Здравствуйте, fk0, Вы писали:

fk0> I want to discuss the possibility of the implementation of some

fk0>programming technique, which allows to use synchronization primitives,
fk0>especially mutexes, seamlessly, like this can be done in C++ with
fk0>std::lock_guard.
На практике можно использовать __attribute__((cleanup)) и не заморачиваться. Поддерживается GCC, clang, icc. А на MSVC уже можно забить.
Sapienti sat!
Re[2]: scoped lock in plain C (similar to
От: fk0 Россия  
Дата: 14.12.21 11:03
Оценка: -1
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, fk0, Вы писали:


fk0>> I want to discuss the possibility of the implementation of some

fk0>>programming technique, which allows to use synchronization primitives,
fk0>>especially mutexes, seamlessly, like this can be done in C++ with
fk0>>std::lock_guard.

C>На практике можно использовать __attribute__((cleanup)) и не заморачиваться. Поддерживается GCC, clang, icc. А на MSVC уже можно забить.


Нельзя. Проблема в том, что во-первых не стандарт, во-вторых, что самое главное, работает
только в рамках функции, а не блока кода. То есть нельзя сделать два вложенных scopes
внутри одной функции. И нельзя окончить scope (не могу подобрать русский термин)
до выхода из функции.

Этот атрибут даёт гораздо худшую и гораздо более ограниченную альтернативу.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.