Чего вам не хватает в языке программирования и в IDE?

Тема в разделе "WASM.ZEN", создана пользователем xcode, 20 апр 2007.

  1. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    ps: что касается лабелов - я предполагал запретить над ними все операции, кроме присваивания (включая взятие адреса), составление из них массивов (или запрет на индексацию таких массивов неконстантными выражениями), а также, возможно, структур, и их использование в аргументах или в качестве возвращаемого значения функции - то есть ничего кроме стандартной функциональности goto
    для переходов между функциями рулит setlong/jumplong.. ))
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    Nouzui
    :)

    Код (Text):
    1. #define TESTVAR1(x, op1) ((x) op1)
    2. #define TESTVAR2(x, op1, op2, op3) (TESTVAR1(x, op1) op2 TESTVAR1(x, op3))
    3. #define TESTVAR3(x, op1, op2, op3, op4, op5) \
    4.     (TESTVAR2(x, op1, op2, op3) op4 TESTVAR1(x, op5))
    5. #define TESTVAR4(x, op1, op2, op3, op4, op5, op6, op7) \
    6.     (TESTVAR3(x, op1, op2, op3, op4, op5) op6 \
    7.     TESTVAR1(x, op7))
    8. #define TESTVAR5(x, op1, op2, op3, op4, op5, op6, op7, op8, op9) \
    9.     (TESTVAR4(x, op1, op2, op3, op4, op5, op6, op7) op8 \
    10.     TESTVAR1(x, op9))
    11. #define TESTVAR6(x, op1, op2, op3, op4, op5, op6, op7, op8, op9, op10, op11) \
    12.     (TESTVAR5(x, op1, op2, op3, op4, op5, op6, op7, op8, op9) op10 \
    13.     TESTVAR1(x, op11))
    14.  
    15. #define OR ||
    16. #define AND &&
    17.  
    18. int main()
    19. {
    20.     int x = '3';
    21.  
    22.     if ( TESTVAR6(x, >='0' ,AND, <='9' ,OR, >='A' ,AND, <='F' ,AND, !='5' ,AND, !='C') )
    23.     {
    24.         MessageBeep(-1);
    25.     }
    26.  
    27.     return 0;
    28. }
    число в макросе TESTVARx указывает, сколько будет операций сравнения. Между двумя операциями сравнения должна быть одна логическая.
     
  3. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Nouzui
    мне кажется, достаточно было бы добавить приведение меток к указательному типу. Тогда косвенный переход можно было бы реализовать библиотечной ф-цией типа indirectgoto(void*) (конечно, предполагается, что это будет intrinsic-ф-ция).

    Впрочем такие метки снизили бы возможности для оптимизации, а "глобальные" метки - тем более.
    А setjmp/longjmp я вообще стараюсь не использовать - слишком тяжеловесны.

    Вообще, лучше пользоваться обычным свичом: хороший компилятор сам заменит его косвенным джампом если это будет оптимально.
     
  4. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Nouzui
    green
    MSDN:
    С goto и indirectgoto() ситуация та же.
     
  5. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    rmn
    препроцессор может многое, но это все равно не то - эти макросы не входят в стандартные хидеры, изменив число операндов тебе придется менять и циферку в макросе, и, тем более, как ты расставишь в таком выражении скобки?
    в общем, мелочь, но было бы приятно

    green
    приведение к указателям - это было бы серьезно, ведь при корректном переходе нужно проинициализировать локальные переменные в функции, на которую осуществляется прыжок, учесть состояние регистров, вызвать деструкторы для перемнных покидаемой функции итд итп
    а indirectgoto в общем случае ведет себя совсем некорректно
    а вообще ты прав - для оптимизации это была бы такая задница, что только держись, хотя я не отказался бы видеть такую возможность, ведь никто не заставляет ее использовать, если тебе критично время выполнения
     
  6. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    не может быть!
     
  7. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    maxdiver
    Вообще-то, indirectgoto предполагалась только для для "локальных"(т.е. в рамках одной ф-ции) переходов.
    А необходимость перехода внутрь чужой ф-ции - это следствие ошибки при проектировании. Разрезать ту ф-цию по метке на две и всё.

    Согласен, что indirectgoto была бы значительно хуже для компилятора в плане оптимизации, т.к. адрес перехода неизвестен на этапе компиляции.
     
  8. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    green
    а зачем тогда indirectgoto?
    я это себе как-то вот так представлял:

    Код (Text):
    1. ...
    2. void func(char *s)
    3. {
    4.     label l= true_l;
    5.  
    6.     if(strcmp(s, "true"))
    7.         l= false_l;
    8.  
    9.     goto l;
    10.  
    11. true_l:
    12.     printf("true");
    13.     return;
    14.  
    15. false_l:
    16.     printf("false");
    17. }
    ))
     
  9. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    А я - вот так:
    Код (Text):
    1. void func(char *s)
    2. {
    3.     void * l= &true_l;
    4.  
    5.     if(strcmp(s, "true"))
    6.         l= &false_l;
    7.  
    8.     indirectgoto(l);
    9.  
    10. true_l:
    11.     printf("true");
    12.     return;
    13.  
    14. false_l:
    15.     printf("false");
    16. }
    Смысл в том, чтобы не вводить дополнительных языковых сущностей (вроде типа label), а ограничиться расширением CRT.
     
  10. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    green
    а все ли так просто?

    ...
    goto x;
    {
    vector<int> s;
    ...
    x:
    ...
    }
    компилятор сообщит от том, что джамп идет в обход инициализации s

    ...
    {
    vector<int> s;
    ...
    x:
    ...
    goto x;
    }
    а вот так вот уже покатит

    то есть то ли потребуется запретить косвенный переход (получение адреса) на метки, позволяющие обойти инициализацию переменных, либо (а вот это уже просто изменение языка) выполнять инициализацию при прыжке внутрь блока
    я подразумевал второй вариант
    соответственно, indirectgoto, как библиотечная функция, не будет ничего знать о размещении блоков внутри текста, и не сможет корректно выполнить переход
    сделать это корректно сможет только сам компилятор, для этого и требуется ввести новые типы. причем, обрати внимание, один и тот же оператор goto l; может вызвать инициализацию ряда переменных, может вызвать инициализацию других переменных, либо вообще не вызывать ничего такого. когда речь идет о cpp, приходится учитывать еще и вызов конструкторов с деструкторами при переходе между областями определения каких-либо автоматических объектов.
    то есть, лабелы - это не просто адреса инструкций, а какие-то внутренние идентификаторы, для обработки которых создается отдельный код
    с точки зрения быстродействия и объема кода - чистая задница, тем более противоречащая основной парадигме C - минимальным различиям между сишными операторами и генерируемым машинным кодом
    так что можно усомниться, действительно ли это стоит того
    впрочем, я бы не отказался, ведь если время выполнения становится критичным, этой возможностью можно было бы и не пользоваться
    правда, после введения ряда таких фич це может стать больше смахивающим на паскаль с его вложенными процедурами, строковыми типами и всем таким подобным
    а от операции взятия адреса меток хуже бы не стало, но вот только что с этими адресами было бы делать, непонятно - всякие библиотечные goto желательно использовать по минимуму, а лучше не использовать вообще

    так что, если задуматься, создатели языка, наверное, тоже подумали, прежде чем писать спецификацию
    зато от continue в switch'е, оператора offset и определения функции по typedef'у я бы точно не отказался..
     
  11. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Что-то я не понял, что должен делать continue в switch'e :)
    А вот определение функций по typedef'у - это даже непонятно, почему до сих пор не ввели
     
  12. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    maxdiver

    Код (Text):
    1. LRESULT CALLBACK WinProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    2. {
    3.  
    4. StartSwitch:   
    5.     switch (message)
    6.     {
    7.         ...
    8.  
    9.         case WM_CLOSE:
    10.  
    11.             <долго и упорно чего-то делаем>
    12.  
    13.             PostQuitMessage(0);
    14.             EndDialog(hDlg, 0);
    15.             return TRUE;
    16.  
    17.         case WM_COMMAND:
    18.             {
    19.                 if(LOWORD(wParam)==IDC_BUTTON1)
    20.                 {
    21.                     ...
    22.                     return TRUE;
    23.                 }
    24.                 else
    25.                 if(LOWORD(wParam)==IDC_BUTTON2)
    26.                 {
    27.                     ...
    28.                     return TRUE;
    29.                 }
    30.                 else
    31.                 if(LOWORD(wParam)==IDCANCEL)
    32.                 {
    33.                     <делаем что-то еще>
    34.                     message= WM_CLOSE;
    35.                     goto StartSwitch;
    36.                 }
    37.             }
    конечно, понимаю, вариантов может быть сколько угодно:
    PostMessage(hDlg, WM_CLOSE, 0, 0) - но это возможно только в таком контексте и благодаря существованию функции PostMeessage, ее может и не быть
    вынести <долго и упорно чего-то делаем> в отдельную функцию (но вот только стоит это того?)
    вставить WM_CLOSE после WM_COMMAND - не поможет, потому что переход может потребоватся не только из WM_COMMAND
    сделать два свитча, из первого просто выйти, а WM_CLOSE обрабатывать во втором - уже извраты пошли
    наконец, просто джампнуться на нужный код - но goto он и есть goto

    вот в таких местах мне и хочется заменить goto StartSwitch на continue
     
  13. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    А чего вы вообще с GOTO связались, это же рудимент, только для совместимости. А не нужна была бы совместимость с С, не было бы его вообще, фтопку его.

    Nouzui
    А если бы не сообщил? IMHO не все компиляторы такие умные.
     
  14. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    тогда это просто ппц, а не компилятор..
     
  15. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    Nouzui
    макросы рулят :)

    Код (Text):
    1. #define SWITCH(a) while(true){switch(a)
    2. #define ENDSWITCH break;}
    3.  
    4. int n = 0;
    5.  
    6. SWITCH(n)
    7. {
    8. case 0:
    9.     n++;
    10.     continue;
    11. case 1:
    12.     n++;
    13.     continue;
    14. case 2:
    15.     break;
    16. }ENDSWITCH
    SWITCH/ENDSWITCH забиваем в шаблоны IDE и радуемся.
    А в компилер continue врядли добавят: switch - это ведь не цикл...
     
  16. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Nouzui
    Да, ты прав. Я даже представить боюсь накладные расходы во втором случае. :)
    Однозначно, надо запретить взятие адреса таких меток извне блока. А в С++ даже не знаю...
    Предполагалось, что это будет intrinsic-ф-ция вроде _exception_code или _ReturnAddress в VC. Т.е. CRT-шная чисто номинально.

    Booster
    Не скажи... IMHO, иногда использование goto уместно. Например, надо быстро выйти из многократно вложенных циклов. Рекомендуемое решение - генерация эксепшена - слишком тяжеловесное.
    Кстати, компилятор VC неплохо оптимизирует goto - т.е. во многих случаях инструкции jmp не будет вообще.

    И goto сплошь и рядом встречается в исходниках виндовс (не аргумент, согласен :derisive:).
     
  17. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    rmn
    ты меня уже просто пугаешь )

    goto.. гм
    я тоже за goto
     
  18. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    rmn
    не завидую человеку, который потом будет разбираться в такой проге. :))
     
  19. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    green
    я когда-то так __try __finally оборачивал:
    #define __linear_start __try
    #define __linear_end __finally{}
    #define __linear_leave __leave
    типа, чтоб __leave можно было на goto поменять, если что..
    потом забил )
     
  20. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Nouzui
    Вообще-то это требование стандарта.
    кстати:
    Код (Text):
    1.     goto m;
    2.     vector<int> x;
    3. m:
    нельзя, а
    Код (Text):
    1. m:
    2.     vector<int> x;
    3.     goto m;
    можно, то есть запрещен переход через инициализацию вперед, а если переход назад, то все в порядке, только при этом выполняется деструктор. От така от фигня... :)