avva: (Default)
[personal profile] avva
(только программистам интересно, наверное)

Почему в процедуральных языках, как правило, нет оператора досрочного выхода из блока? Как break в C, но чтобы работал не только из циклов, а также внутри if-then или вообще любого блока.

Постоянно приходится делать глупые вложенные цепочки условий или некрасивые трюки типа while(1) и выполза по break'у (ну или, понятно, их аналоги в других языках).

Есть какая-то глубокая причина этому?

Date: 2003-04-12 05:41 am (UTC)
From: [identity profile] oblomov-jerusal.livejournal.com
А почему в C break может выйти только из самого внутреннего цикла? Почему нельзя написать что-то вроде main_loop: for(...) { .... if (foo) break main_loop;...} Вроде в каком-то языке (Ада?) я что-то подобное видел.

Ещё в C нужен способ определить cleanup (напр. определить, что ресурс, запрошенный в начале функции или блока должен быть освобожден при любом выходе из нее/него), и способ определить структуру состоящую из заголовка за которым следует часть, которая повторяется неизвестное при компиляции число раз вроде


typedef struct _s_nametable_ {
   int count; 
   struct _s_nametable_ *next_nametable;
   struct {
      int value;
      char *name;
   } names[];
} nametable_t;
nametable_t *nametable = malloc(sizeof nametable_t(100));
nametable->names[i].name = "bar";
где для namеtable выделяется место для заголовка и массива names из 100 элементов

Re:

Date: 2003-04-12 07:24 am (UTC)
From: [identity profile] avva.livejournal.com
В Джаве есть такой выход из вложенных циклов.

В C, по-моему, нет cleanup'а по двум причинам, в чём-то друг от друга зависящим: во-первых, железо начала 70-х (речь идёт не о мейнфреймах, конечно) его плохо поддерживало; во-вторых, C изначально был задуман как язык, в котором все переходы контроля абсолютно прозрачны для программиста. В C никогда ничего не происходит "за кулисами" с точки зрения выполнения каких-то команд. Именно поэтому сторонники других языков любят называть C макроассемблером, но, с другой стороны, это идеально подходит для системного кода, для realtime-кода, и вообще во всех случаях, когда программист должен более или менее чётко представлять, что происходит во время исполнения вот этой конкретной строки кода.

Структура динамического размера - да, было бы удобно, хотя это syntactic sugar, по сути дела.

Date: 2003-04-12 08:05 am (UTC)
From: [identity profile] oblomov-jerusal.livejournal.com
Я не language lawyer, но насколько я понимаю, написание кода, аналогичного структуре динамического размера невозможно в пределах стандарта ANSI C (например, стандарт не гарантирует того, что последнее поле в определении структуры будет последним в памяте).

Date: 2003-04-12 10:45 am (UTC)
From: [identity profile] tejblum.livejournal.com
например, стандарт не гарантирует того, что последнее поле в определении структуры будет последним в памяте.

Кажется, стандарт это всё же гарантирует, во всяком случае последний стандарт (т.н. C99). В C99 также есть и поддержка таких вот структур переменной длинны, с массивом неизвестного размера в качестве последнего элемента. Только память выделять надо так: malloc(sizeof(nametable_t) + 100*sizeof(nametable->names[0])). В gcc 3.1 это даже работает.

Date: 2003-04-12 11:02 am (UTC)
From: [identity profile] oblomov-jerusal.livejournal.com
Ну примерно так я всегда писал, только стандартно ли это? Мне кажется более стандартным (но не стандартным) вариантом malloc(offsetof(nametable_t, names) + 100 * sizeof(nametable->names[0]));

Date: 2003-04-12 11:19 am (UTC)
From: [identity profile] tejblum.livejournal.com
Я же говорю: в C99, то есть в стандарте C от 1999 года, стандартно можно не указывать размер последнего поля-массива в структуре. В старом стандарте С (от 1989 года) можно было у последнего массива указывать размер 1 и писать offsetof; это абсолютно стандартно, и продолжает быть стандартным в C99.

Date: 2003-04-12 11:04 am (UTC)
From: [identity profile] tejblum.livejournal.com
Первые версии C++, до появления exceptions (но с конструкторами, деструкторами и виртуальными функциями) вполне можно считать тем же макропроцессором (а cleanup, который хотел [livejournal.com profile] oblomov_jerusal -- это и есть деструктор). Темплейты этой макропроцессорности тоже не мешают. Эта черта языка мне очень нравится.

Date: 2003-04-12 09:29 am (UTC)
From: [identity profile] ex-ilyavinar899.livejournal.com
В Аде можно сказать "L: loop ... M: loop... exit loop L; ... end loop; end loop;" (не смотрел на Аду лет 14, может, ошибаюсь в синтаксисе). Также, по-моему, что-то подобное есть в PL/I.

cleanup есть в расширениях Visual C++: __try / __finally. Также в Visual C++ есть подобная структура: names[0];.

Re:

Date: 2003-04-12 09:36 am (UTC)
From: [identity profile] avva.livejournal.com
Я когда-то сделал reverse engineering того, как в Visual C++ работают exceptions, для одного проекта. Обнаружил, что они требуют любопытной недокументированной кооперации между компилятором и ОС. Продокументировал это и послал, кажется, в ньюсгруппу какую-то (а может, забыл).

Re:

Date: 2003-04-12 09:47 am (UTC)
From: [identity profile] ex-ilyavinar899.livejournal.com
О да. В Microsoft Outlook для exceptions используются собственные ассемблерные макросы, и мой сосед по оффису когда-то портировал Office 97 на DEC Alpha, и совсем заколебался с этими макросами.

Date: 2003-04-12 08:26 pm (UTC)
From: [identity profile] oblomov-jerusal.livejournal.com
_try/_finally соответствует exceptions в C++? Я имел в виду что-нибудь более легковесное, что отслеживает выходы по return, break, goto и т.д. т.е то, что можно отследить во время компиляции.

Re:

Date: 2003-04-12 08:27 pm (UTC)
From: [identity profile] ex-ilyavinar899.livejournal.com
Тогда деструкторы.

Date: 2003-04-12 08:41 pm (UTC)
From: [identity profile] 109.livejournal.com
> Ещё в C нужен способ определить cleanup

во всех современных языках есть try-finally, которая для этого и предназначена.

January 2026

S M T W T F S
    1 2 3
45678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 5th, 2026 12:29 pm
Powered by Dreamwidth Studios