LINUX.ORG.RU

Разрешено использование C++ в GCC

 , , , , ,


0

1

Вчера в списке рассылки GCC появилось важное сообщение по поводу использования языка программирования C++ при разработке GCC (GNU Compiler Collection, а не сам компилятор языка C).

Марк Митчелл (Mark Mitchell), один из основных разработчиков GCC:

Я рад сообщить, что руководящий комитет GCC и FSF одобрили использование C++ в самом GCC. Конечно, нет никаких причин использовать возможности С++ только потому, что мы умеем это делать. Главная цель - предоставить пользователям более качественные компиляторы, а не кодовую базу на C++ для самих себя.

Перед тем, как мы действительно начнём использовать C++, мы должны определиться с набором правил, которыми нужно будет руководствоваться при использовании C++ для разработки GCC. Я считаю, что для начала мы должны минимизировать список разрешённых возможностей С++, чтобы не подвергать разработчиков GCC, не знакомых с C++, таким резким переменам в основном языке разработки компиляторов. Мы всегда сможем расширить использование С++ позднее, если появится такая необходимость.

На данный момент разработчики ограничиваются стандартом C++98 и использованием типа long long для 64-битных целых чисел. Использование множественного наследования, шаблонов (тех, которые не входят в стандартную библиотеку C++) и исключений, скорее всего, будет запрещено. Это мотивировано тем, что это будет сложно для программистов на C, а также тем, что сами программисты C++ могут с лёгкостью допустить ошибки в таких вещах.

Так как язык C++ достаточно обширен, то Марк Митчелл предложил составить список того, что разрешается использовать, а не того, что использовать нельзя. На данный момент необходимо составить некоторые информационные нормативы, а не очередной стандарт ISO.

Все желающие поучаствовать в разработке нормативов могут связаться с разработчиками GCC. На данный момент предполагается сделать это в виде странички в Wiki.

>>> Официальный анонс

★★★★

Проверено: JB ()

Ответ на: комментарий от lester

после просмотра результата компиляции функции B - особенно хорошо видно как исключения «ничего не стоят»

lester ★★★★ ()
Ответ на: комментарий от SergikXP

> Ну что, последователи Линуса, С++ ненавистники... выкусили? :)...

Именно, что выкусили. Причём, после выкусывания в результате обнаружился знакомые нотки паскаля. :)

atrus ★★★★★ ()

... и придет С++ в наш мир, и живые будут завидовать мертвым .

mirocumo ()
Ответ на: комментарий от lester

Бгг, ну и криворучка же ты. Смотри, как надо:

$ cat c.cc         
int f(int);                                      

int h_ex(int arg)
{                
        try      
        {
                return f(arg);
        }
        catch(...)
        {
                return arg;
        }
}

int h_no_ex(int arg)
{
        int t = f(arg);
        if(t != -1)
        {
                return t;
        }
        else
        {
                return arg;
        }
}

$ g++ -O2 -c c.cc

$ objdump -d -C c.o

c.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <h_no_ex(int)>:
   0:   53                      push   %rbx
   1:   89 fb                   mov    %edi,%ebx
   3:   e8 00 00 00 00          callq  8 <h_no_ex(int)+0x8>
   8:   83 f8 ff                cmp    $0xffffffffffffffff,%eax
   b:   0f 44 c3                cmove  %ebx,%eax
   e:   5b                      pop    %rbx
   f:   c3                      retq

0000000000000010 <h_ex(int)>:
  10:   53                      push   %rbx
  11:   89 fb                   mov    %edi,%ebx
  13:   e8 00 00 00 00          callq  18 <h_ex(int)+0x8>
  18:   5b                      pop    %rbx
  19:   c3                      retq
  1a:   48 89 c7                mov    %rax,%rdi
  1d:   e8 00 00 00 00          callq  22 <h_ex(int)+0x12>
  22:   e8 00 00 00 00          callq  27 <h_ex(int)+0x17>
  27:   89 d8                   mov    %ebx,%eax
  29:   5b                      pop    %rbx
  2a:   c3                      retq

При использовании исключений нет накладых расходов на проверку результата и нет накладных расходов на блок try/cath. Код использующий исключения не только не медленнее, а даже быстрее.

Manhunt ★★★★★ ()
Ответ на: комментарий от lester

>как исключения «ничего не стоят»

в нормальных языках. зачем на C++ компилятор делать?

anonymous ()
Ответ на: комментарий от Manhunt

>Оптимизирующий компилятор - это крайне сложная, высокоуровневая программа. Писать его на столь низкоуровнем языке как Си - неоправданно трудоемко. Что признал руководящий комитет GCC.

А почему бы тогда не написать его сразу на Питоне?

anonymous ()
Ответ на: комментарий от lester

> ты идиот или притворяешься?

Идиотизм твоего примера выдает в тебе хеллоуворлдщика :)

у тебя в программах нет вложенных процедур и соб-но бросков исключений?


По-твоему что такое функция f()? И с какого бодуна ты решил, что она не кидает исключений?

ты еще try{}catch(...){} с -О2 собери


Просвети, а с какими опциями обычно компилируются хеллоуворлдщики?

Manhunt ★★★★★ ()

бедные гццшники. весь цивилизованный мир уже давно пишет компиляторы на плюсах, причем без ограничений на возможности языка

annulen ★★★★★ ()
Ответ на: комментарий от anonymous

> А почему бы тогда не написать его сразу на Питоне?

У питона плоховато с производительностью.

Manhunt ★★★★★ ()

Не понимаю: почему нельзя было просто использовать g++ для C++? В результате же получилась ни рыба ни мясо.

anonymous ()
Ответ на: комментарий от lester

>> Проверки возвращаемых значение тоже не бесплатны, зато исключения надежней.

в чем именно они надежней?

При использовании исключения нужно позаботиться всего о двух местах в коде — том, которое генерирует исключение и том, которое обрабатывает. В случае же традиционного структурного подхода надо не забывать проверять возвращаемые значения во всех местах, где вызывается функция и корректно обрабатывать ошибку на всех уровнях вложенности вызовов.

Relan ★★★★★ ()
Ответ на: комментарий от Manhunt

>Оптимизирующий компилятор - это крайне сложная, высокоуровневая программа. Писать его на столь низкоуровнем языке как Си - неоправданно трудоемко. Что признал руководящий комитет GCC.

А почему бы тогда не написать его сразу на Питоне?

anonymous ()
Ответ на: комментарий от Manhunt

> Идиотизм твоего примера выдает в тебе хеллоуворлдщика :)

мой пример показывает, что ВНЕЗАПНО иногда кроме обработки исключений надо их соб-но кидать, и что даже если броска нет - лишние действия все-равно проиизводятся

о-твоему что такое функция f()? И с какого бодуна ты решил, что она не кидает исключений?


а почему ты ее не показал? хотя я знаю - потому-что она пустая

Просвети, а с какими опциями обычно компилируются хеллоуворлдщики?


не знаю - тебе виднее

lester ★★★★ ()
Ответ на: комментарий от anonymous

>Не понимаю: почему нельзя было просто использовать g++ для C++? В результате же получилась ни рыба ни мясо.

Все, я понял, что я тормоз. Можете не отвечать. :)

anonymous ()
Ответ на: комментарий от Relan

> При использовании исключения нужно позаботиться всего о двух местах в коде — том, которое генерирует исключение и том, которое обрабатывает.

Увы, этого не достаточно. Код должен быть написан так, чтобы при раскрутке стека не потерять каких-нибудь ресурсов. Память, дескрипторы, и тд. Кроме того, если код написан неправильно, прерванный из-за исключения метод может оставить объект в неконсистетном состоянии.

Manhunt ★★★★★ ()
Ответ на: комментарий от anonymous

>А почему бы тогда не написать его сразу на Питоне?

g++ и без того тормозит

annulen ★★★★★ ()
Ответ на: комментарий от lester

>и что даже если броска нет - лишние действия все-равно проиизводятся

я помню, что была статья, где исключения в плюсах как оптимизацию юзали (когда их вероятность мала). и страуссруп тоже писал, что без броска они почти ничего не стоят. какой-то ты хуевый плюсатник.

anonymous ()
Ответ на: комментарий от lester

а меня отругали, когда я без спроса вырубил исключения (-fno-exceptions) для части модулей проекта, где они не использовались

annulen ★★★★★ ()
Ответ на: комментарий от Manhunt

>> При использовании исключения нужно позаботиться всего о двух местах в коде — том, которое генерирует исключение и том, которое обрабатывает.

Увы, этого не достаточно. Код должен быть написан так, чтобы при раскрутке стека не потерять каких-нибудь ресурсов. Память, дескрипторы, и тд. Кроме того, если код написан неправильно, прерванный из-за исключения метод может оставить объект в неконсистетном состоянии.

Разумеется все ресурсы должны быть оформлены в виде объектов с конструкторами и деструкторами. На то он и ООП. :)

Relan ★★★★★ ()
Ответ на: комментарий от anonymous

> я помню, что была статья, где исключения в плюсах как оптимизацию юзали (когда их вероятность мала). и страуссруп тоже писал, что без броска они почти ничего не стоят. какой-то ты хуевый плюсатник.

без броска - это стоит один jmp, проверка стоит mov+cmp+jmp, но каждый catch + throw - это лишний код и не маленький( который Manhunt «умело» скрыл в своем «примере» ), а чем раздутей код - тем больше вероятность, что он не влезет в кэш

lester ★★★★ ()
Ответ на: комментарий от vadiml

> И какой тогда смысл использовать C++ ? А ещё можно запретить возможности С, которых нет в ассемблере, т.к. это будет сложно для программистов asm-a

насчет сложности — это и правда ерунда, а вот смысл использовать ООП-шную компоненту есть, даже без исключений

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от lester

>> о-твоему что такое функция f()? И с какого бодуна ты решил, что она не кидает исключений?

а почему ты ее не показал? хотя я знаю - потому-что она пустая


Можешь затолкать свои «зания» назад в свой хеллоуворлд. Этой функции не видел ни компилятор, ни ты, ни я: она просто физически еще не написана. Компилятор ее никогда и не увидит: она будет доступна только на стадии линковки. При этом код, порожденный компилятором, готов к тому, что она бросит исключение.

кроме обработки исключений надо их соб-но кидать


Еще раз: не требуется, чтобы кидание исключения было быстрым. На то оно и исключение, что возникает редко.

Manhunt ★★★★★ ()
Ответ на: комментарий от Relan

>Проверки возвращаемых значение тоже не бесплатны, зато исключения надежней.

А исключения, значит, сами по себе возникают а не на основе проверки возвращаемых значений?

linuxfan ()
Ответ на: комментарий от lester

Вот я сейчас по быстрому проверил. Код с эксепшном выполняется лишь на 2% медленнее чем без эксепшна.

Rudcozt ()

если запретить try/catch и полностью запретить STL тогда еще куда не шло... но сомнительно что так будет... даже std::string может кидать исключения... уровень бардака в коде думаю резко возрастет...

xtron ()
Ответ на: комментарий от Manhunt

>> Еще раз: не требуется, чтобы кидание исключения было быстрым. На то оно и исключение, что возникает редко.

А как же знаменитый антипаттерн «Подгузник» ? :)

Лично я видел пример когда человек условную логику на исключениях делал, вот кому бы скорость пригодилась.

EvilBlueBeaver ()
Ответ на: комментарий от lester

> криво написать можно используя любой подход - в том числе и

исключения, а качественные сишные библиотеки не так уж и страшны


Хм, ты считаешь, что С++ не нужен?

archimag ★★★ ()
Ответ на: комментарий от lester

> и да - на вложенных try/throw появляется неилюзорный лишний код, который всегда дороже проверки

я тестировал исключения, и при их достаточно малом проценте плюсовый код работает как сишный или быстрее; вот мои тестовые проги

http://www.linux.org.ru/forum/development/3856841

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от lester

>, а чем раздутей код - тем больше вероятность, что он не влезет в кэш

чисто гадание на кофейной гуще. и медленный код, который отработает менее чем в 1% случаев, в кеше не нужен.

anonymous ()
Ответ на: комментарий от xtron

Угу, и для этого разрабы gcc напишут свой собственный вариант STL для внутреннего пользования... идиотизм.

BlackV ()

Оригинал: For example, I think it goes without question that at this point we are limiting ourselves to C++98 (plus «long long» so that we have a 64-bit integer type); C++0x features should not be used. Using multiple inheritance, templates (other than when using the C++ standard library, e.g. std::list<X>), or exceptions also seems overly aggressive to me. We should use features that are relatively easy for C programmers to understand and relatively hard for new C++ programmers to misuse. (For example, I think constructors and destructors are pretty easy and hard to misuse.)

Речь вроде идёт о неюзании С++0х фич. Об остальных идёт речь, что это не простые вещи. Об их запрете не упоминается...

SergikXP ()

М-да, опять будет срач, а ведь никто ничего еще толком не использует.

PayableOnDeath ()
Ответ на: комментарий от lester

> чем раздутей код - тем больше вероятность, что он не влезет в кэш

Вот ты и не потянул на троечку по своей же шкале. В кэш попадает лишь тот код, который фактически выполняется процессором. Если throw и catch секции управление не получают, то и кэша они почти не занимают. Подучи на досуге, имеют ввиду под словом «ассоцативный», когда говорят о кэшах.

> каждый catch + throw - это лишний код и не маленький( который Manhunt «умело» скрыл в своем «примере» )

Идиотушка, запомни: catch - сами по себе (и ты видел, что они ничего не стоят, пока не нужно передавать им управение), throw - сами по себе. Давай посмотрим, чего стоят throw.

$ cat d.cc
int g(int);                             

class MyException
{                
};               

int f_ex(int arg)
{                
        if(arg==0)
                throw MyException();
        int t = g(arg);             
        if(t==0)                    
                throw MyException();
        return t;                   
}

int f_no_ex(int arg)
{
        if(arg==0)
                return -1;
        int t = g(arg);
        if(t==0)
                return -1;
        return t;
}

$ g++ -c -O2 d.cc

$ objdump -d -C d.o

d.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <f_no_ex(int)>:
   0:   48 83 ec 08             sub    $0x8,%rsp
   4:   85 ff                   test   %edi,%edi
   6:   75 10                   jne    18 <f_no_ex(int)+0x18>
   8:   b8 ff ff ff ff          mov    $0xffffffff,%eax
   d:   48 83 c4 08             add    $0x8,%rsp
  11:   c3                      retq
  12:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  18:   e8 00 00 00 00          callq  1d <f_no_ex(int)+0x1d>
  1d:   ba ff ff ff ff          mov    $0xffffffff,%edx
  22:   85 c0                   test   %eax,%eax
  24:   0f 44 c2                cmove  %edx,%eax
  27:   eb e4                   jmp    d <f_no_ex(int)+0xd>
  29:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000000030 <f_ex(int)>:
  30:   48 83 ec 08             sub    $0x8,%rsp
  34:   85 ff                   test   %edi,%edi
  36:   74 0e                   je     46 <f_ex(int)+0x16>
  38:   e8 00 00 00 00          callq  3d <f_ex(int)+0xd>
  3d:   85 c0                   test   %eax,%eax
  3f:   74 05                   je     46 <f_ex(int)+0x16>
  41:   48 83 c4 08             add    $0x8,%rsp
  45:   c3                      retq
  46:   bf 01 00 00 00          mov    $0x1,%edi
  4b:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  50:   e8 00 00 00 00          callq  55 <f_ex(int)+0x25>
  55:   31 d2                   xor    %edx,%edx
  57:   be 00 00 00 00          mov    $0x0,%esi
  5c:   48 89 c7                mov    %rax,%rdi
  5f:   e8 00 00 00 00          callq  64 <f_ex(int)+0x34>

В случае с исключениями компилятор знает, что они возникают редко, и поэтому переместил код их бросания куда подальше, а «горячий» код расположил «вподряд», инструкцию за инструкцией.

В случае с if-ами компилятор не знает, какой случай чаще. Поэтому «горячий» код выполняет jne и перемежается (с редко выполняемым) кодом обработки возварщения -1. C точки зрения кэша такой код как раз является распухшим.

Manhunt ★★★★★ ()
Ответ на: комментарий от EvilBlueBeaver

> Лично я видел пример когда человек условную логику на исключениях делал, вот кому бы скорость пригодилась.

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

Manhunt ★★★★★ ()
Ответ на: комментарий от Manhunt

а теперь выкинь переменную из своего примера «if(f(arg) != -1)» и сравни две команды над регистрами с одной со стеком

Еще раз: не требуется, чтобы кидание исключения было быстрым. На то оно и исключение, что возникает редко.

__Z1Bv:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $108, %esp
movl $___gxx_personality_sj0, -68(%ebp)
movl $LLSDA8, -64(%ebp)
leal -60(%ebp), %eax
leal -24(%ebp), %edx
movl %edx, (%eax)
movl $L12, %edx
movl %edx, 4(%eax)
movl %esp, 8(%eax)
leal -92(%ebp), %eax
movl %eax, (%esp)
call __Unwind_SjLj_Register
movl $2, -88(%ebp)
call __Z1Cv
jmp L10

это «реакция» gcc на код где просто при словленном исключении идет его проброска( бросок другого ) - тоже нереальный случай?

lester ★★★★ ()
Ответ на: комментарий от Manhunt

> Вот ты и не потянул на троечку по своей же шкале. В кэш попадает лишь тот код, который фактически выполняется процессором. Если throw и catch секции управление не получают, то и кэша они почти не занимают. Подучи на досуге, имеют ввиду под словом «ассоцативный», когда говорят о кэшах.

ололо, какой ты фантазер :) процессор не вырезает блоки памяти, а потом склеивает, а копирует целиком

запомни: catch - сами по себе (и ты видел, что они ничего не стоят, пока не нужно передавать им управение), throw - сами по себе


а ты еще тугодумней чем казалось - я тебе уже привел пример, когда это не так, напряги извилину

lester ★★★★ ()
Ответ на: комментарий от Manhunt

> В случае с исключениями компилятор знает, что они возникают редко, и поэтому переместил код их бросания куда подальше, а «горячий» код расположил «вподряд», инструкцию за инструкцией.

ты сначала примеры разнозначные напиши - а потом что-то сравнивай

lester ★★★★ ()
Ответ на: комментарий от Manhunt

>Больше велосипедов, кривых и убогих?

А STL разве не кривой и убогий? Взять, к примеру, его на голову больную концепцию аллокаторов.

linuxfan ()

Ну всё, после этого GCC точно R.I.P. Использовать C++ для написания компилятора это то же самое, что использовать его для системного программирования. Ждём нормальный clang-llvm в Линуксе.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.