1. Си / Говнокод #4264

    +98

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    //
    // Замена блоков __try/__finally нашей реализацией. Примеры использования:
    // NTSTATUS SomeFunc() {
    //     X *p = NULL;
    //     NTSTATUS status = STATUS_SUCCESS;
    //     Try {
    //         p = new(NonPagedPool) X;
    //         if (!p) Leave(status = STATUS_INSUFFICIENT_RESOURCES);
    //
    //         status = SomeKernelFunc();
    //         LeaveNS(status = STATUS_UNSUCCESSFUL);
    //     } Finally {
    //         if (p) delete p;
    //     }
    //     return status;
    // }
    //
    #define Try if (1)
    #define Finally try_exit: NOTHING
    #define Leave(s) { s; goto try_exit; }
    #define LeaveNS(s) {if (!NT_SUCCESS(status)) Leave(s);}
    #define Run(s) {status = s; LeaveNS(;);}

    Суровые исключения для Win32 драйвера

    Запостил: rat4, 16 Сентября 2010

    Комментарии (7) RSS

    • 0_0. просто жесть.
      Ответить
    • Так-так ... в примере не используется #define Run => говенный пример :))
      P.s. велик и могуч препроцессор си
      Ответить
      • А вот и пример с Run :)
        /// Переименовываем файл
        NTSTATUS XXXFile::FullRename(PUNICODE_STRING RelDosPathName, BOOLEAN ReplaceIfExists) {
            XXXFile *pTarget = NULL;
            NTSTATUS status = STATUS_SUCCESS;
        
            Try {
                XXX_NEWOBJ(pTarget, XXXFile(m_pFsDevice));
                Run(pTarget->OpenCreate(RelDosPathName, NULL, SYNCHRONIZE,
                        OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, 0, FILE_SHARE_VALID_FLAGS,
                        FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, m_Flag, NULL, 4));
                Run(InternalRename(pTarget->FileObject(), (HANDLE)pTarget, ReplaceIfExists));
            } Finally {
                XXX_DELETE(pTarget);
            }
            return status;
        }
        Ответить
    • Для того, чтобы судить о говенности подобного кода надо сначала выяснить, что вынудило авторов прибегнуть к подобным приемам. Если у них есть на то веские причины - то вполне возможно что данное решение вполне приемлемо (если в нем нет каких-то частных огрехов, я внимательно не смотрел). В жизни всяко бывает: и баги компиляторов приходится обходить, и чрезмерную тяжесть реализаций стандартных фич языка, и т.п.
      Ответить
      • ...хотя, конесно, за незнакомство с приемом `do { ... } while (0)` (или за умышленное его неиспользование) при написании макросов по голове гладить не стоит.
        Ответить
      • т.е. приходится изобретать свои велосипеды?
        Ответить
    • Такие конструкции нередки при портировании с C++ на чистый C
      Ответить

    Добавить комментарий