LINUX.ORG.RU — Русская информация об ОС Linux

[#]  
MuZHiK-2 (фотография)

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

Вчера в списке рассылки 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.

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

Метки: c, c++, fsf, gcc, gnu, программирование

MuZHiK-2 *** (31.05.2010 14:00:10)
Проверено: JB (31.05.2010 14:27:30)
Juick

[#] Ответ на: комментарий от lester 31.05.2010 16:54:57  

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

lester **** (31.05.2010 17:06:13)
[#]  

Ну вот, теперь товарищу Торвальдсу придется писать свой компилятор.

paran0id * (31.05.2010 17:06:48)
[#] Ответ на: комментарий от SergikXP 31.05.2010 15:01:19  
atrus (фотография)

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

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

atrus ***** (31.05.2010 17:13:56)
[#]  
mirocumo (фотография)

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

mirocumo (31.05.2010 17:15:29)
[#] Ответ на: комментарий от lester 31.05.2010 16:57:04  
Manhunt (фотография)

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

$ 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 *** (31.05.2010 17:18:18)
[#] Ответ на: комментарий от lester 31.05.2010 17:06:13  

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

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

anonymous (31.05.2010 17:18:34)
[#]  
pevzi (фотография)

Чо, срач C vs C++?

pevzi **** (31.05.2010 17:21:50)
[#] Ответ на: комментарий от Manhunt 31.05.2010 17:18:18  

ты идиот или притворяешься? ты еще try{}catch(...){} с -О2 собери

lester **** (31.05.2010 17:25:27)
[#] Ответ на: комментарий от Manhunt 31.05.2010 15:13:03  

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

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

anonymous (31.05.2010 17:27:22)
[#] Ответ на: комментарий от lester 31.05.2010 17:25:27  
Manhunt (фотография)

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

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

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


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

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


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

Manhunt *** (31.05.2010 17:28:04)
[#]  
annulen (фотография)

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

annulen ** (31.05.2010 17:28:38)
[#] Ответ на: комментарий от pevzi 31.05.2010 17:21:50  
wingrime (фотография)

неужели ковото спецально заставляют использовать с++

wingrime * (31.05.2010 17:28:50)
[#] Ответ на: комментарий от anonymous 31.05.2010 17:27:22  
Manhunt (фотография)

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

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

Manhunt *** (31.05.2010 17:29:12)
[#]  

Goodnight, sweet prince.

mix_mix * (31.05.2010 17:29:24)
[#]  

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

anonymous (31.05.2010 17:30:10)
[#] Ответ на: комментарий от gRAyNDEr 31.05.2010 14:15:41  
annulen (фотография)

>gcc - монополист (в *nix системах)

o rly?

annulen ** (31.05.2010 17:30:53)
[#] Ответ на: комментарий от lester 31.05.2010 15:02:52  

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

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

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

Relan **** (31.05.2010 17:30:57)
[#] Ответ на: комментарий от Manhunt 31.05.2010 15:13:03  

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

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

anonymous (31.05.2010 17:31:22)
[#]  
mikhalich (фотография)

ждем последствий

mikhalich ** (31.05.2010 17:32:01)
[#] Ответ на: комментарий от Manhunt 31.05.2010 17:28:04  

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

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

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


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

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


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

lester **** (31.05.2010 17:32:39)
[#] Ответ на: комментарий от anonymous 31.05.2010 17:30:10  

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

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

anonymous (31.05.2010 17:33:54)
[#] Ответ на: комментарий от Relan 31.05.2010 17:30:57  
Manhunt (фотография)

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

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

Manhunt *** (31.05.2010 17:34:59)
[#] Ответ на: комментарий от anonymous 31.05.2010 17:27:22  
annulen (фотография)

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

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

annulen ** (31.05.2010 17:36:34)
[#] Ответ на: комментарий от lester 31.05.2010 17:32:39  

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

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

anonymous (31.05.2010 17:38:07)
[#] Ответ на: комментарий от lester 31.05.2010 16:54:57  
annulen (фотография)

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

annulen ** (31.05.2010 17:39:09)
[#] Ответ на: комментарий от Manhunt 31.05.2010 17:34:59  

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

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

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

Relan **** (31.05.2010 17:44:45)
[#] Ответ на: комментарий от anonymous 31.05.2010 17:38:07  

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

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

lester **** (31.05.2010 17:44:54)
[#] Ответ на: комментарий от lester 31.05.2010 17:44:54  

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

lester **** (31.05.2010 17:46:01)
[#] Ответ на: комментарий от vadiml 31.05.2010 14:47:34  
www_linux_org_ru (фотография)

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

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

www_linux_org_ru **** (31.05.2010 17:46:29)
[#] Ответ на: комментарий от wingrime 31.05.2010 17:28:50  
pevzi (фотография)

> ковото спецально

-_-

pevzi **** (31.05.2010 17:46:47)
[#] Ответ на: комментарий от lester 31.05.2010 17:32:39  
Manhunt (фотография)

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

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


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

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


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

Manhunt *** (31.05.2010 17:46:56)
[#] Ответ на: комментарий от Relan 31.05.2010 14:57:25  

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

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

linuxfan * (31.05.2010 17:47:54)
[#] Ответ на: комментарий от lester 31.05.2010 16:57:04  

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

Rudcozt (31.05.2010 17:47:59)
[#]  
xtron (фотография)

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

xtron * (31.05.2010 17:48:14)
[#] Ответ на: комментарий от Manhunt 31.05.2010 17:46:56  
EvilBlueBeaver (фотография)

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

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

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

EvilBlueBeaver * (31.05.2010 17:49:26)
[#] Ответ на: комментарий от lester 31.05.2010 16:52:10  

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


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

archimag ** (31.05.2010 17:50:07)
[#] Ответ на: комментарий от lester 31.05.2010 17:46:01  
www_linux_org_ru (фотография)

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

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

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

www_linux_org_ru **** (31.05.2010 17:51:13)
[#] Ответ на: комментарий от lester 31.05.2010 17:44:54  

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

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

anonymous (31.05.2010 17:54:34)
[#] Ответ на: комментарий от xtron 31.05.2010 17:48:14  
BlackV (фотография)

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

BlackV (31.05.2010 17:54:50)
[#]  
SergikXP (фотография)

Оригинал: 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 (31.05.2010 17:55:33)
[#] Ответ на: комментарий от paran0id 31.05.2010 17:06:48  
oh (фотография)

Надеюсь таки напишет

oh (31.05.2010 17:56:25)
[#]  

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

PayableOnDeath * (31.05.2010 18:00:45)
[#] Ответ на: комментарий от lester 31.05.2010 17:44:54  
Manhunt (фотография)

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

Вот ты и не потянул на троечку по своей же шкале. В кэш попадает лишь тот код, который фактически выполняется процессором. Если 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 *** (31.05.2010 18:03:13)
[#] Ответ на: комментарий от EvilBlueBeaver 31.05.2010 17:49:26  
Manhunt (фотография)

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

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

Manhunt *** (31.05.2010 18:06:43)
[#] Ответ на: комментарий от Manhunt 31.05.2010 17:46:56  

а теперь выкинь переменную из своего примера "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 **** (31.05.2010 18:10:59)
[#] Ответ на: комментарий от xtron 31.05.2010 17:48:14  
Manhunt (фотография)

> полностью запретить STL

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

Manhunt *** (31.05.2010 18:15:07)
[#] Ответ на: комментарий от Manhunt 31.05.2010 18:03:13  

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

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

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


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

lester **** (31.05.2010 18:16:43)
[#] Ответ на: комментарий от Manhunt 31.05.2010 18:03:13  

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

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

lester **** (31.05.2010 18:18:46)
[#] Ответ на: комментарий от Manhunt 31.05.2010 18:15:07  

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

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

linuxfan * (31.05.2010 18:26:07)
[#]  

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

anonymous (31.05.2010 18:26:09)

О Сервере - Правила форума
http://www.linux.org.ru/

Rambler's Top100 Рейтинг@Mail.ru