Найбільш захоплюючою особливістю Carbon є його умовність викликів
Минулого тижня Чендлер Керрут анонсував Carbon, потенційну заміну C++, над якою він працював протягом двох років. Він має звичайні круті функції, яких ви очікуєте від сучасної мови: корисні генерики, інтерфейси компілятора/риси/концепції, модулі тощо. .
Це те, про що я сам думав у минулому, і, наскільки мені відомо, ніколи раніше не робилося мовою низького рівня, але ця концепція має великий потенціал. Дозвольте мені пояснити, про що я говорю.
Передача вуглецевих параметрівЗа замовчуванням, тобто якщо ви більше нічого не пишете, параметри Carbon передаються через еквівалент const T& у C++.
бал класу { змінна x: i64; змінна y:i64; змінна z:i64; } fn Print(p: Dot); точка попадання { std::uint64_t x, y, z; }; void Print(const Point&p);Проте - і це частина імпорту - компілятору дозволено перетворити це на T згідно з правилом "як ніби".
fn Print(x: i32); void Print(std::int32_tx);... і що? Чому я так радію цьому?
Перевага №1: ПродуктивністьПропускати речі через const T& завжди добре, чи не так? Зрештою, ви уникаєте копії!
Хоча це правда, посилання по суті є покажчиками на рівні збірки. Це означає, що передача аргументу через const T& встановлює регістр на його адресу, що означає
у викликаючому аргументі потрібна адреса, і він повинен зберігатися десь у пам’яті, і у callee, параметр повинен завантажити значення з пам'яті під час його читання.Це єдині варіанти для типів, які не вміщуються в реєстр, або невеликих типів із нетривіальними конструкторами копіювання, але вони менш ідеальні для тривіально скопійованих типів, які підходять.
Порівняйте збірку між функцією add, яка отримує свої аргументи через const T&
[[gnu::noinline]] int add(const int& a, const int& b) { повернути a + b; } int foo() { повертає add(11, 42); }і той, хто цього не робить
[[gnu::noinline]] int add(int a, int b) { повернути a + b; } int foo() { повертає add(11, 42); }Усі сховища та завантаження пам’яті зникають; ви не хочете переходити за посиланням!
Тож дуже добре, що в Carbon вам не потрібно думати про це – компілятор просто зробить правильні речі за вас. Крім того, ви не завжди можете зробити це вручну.
Перевага №2: Оптимальна домовленість про виклики в загальному кодіПрипустімо, ми хочемо написати загальну функцію друку на C++. Тип може бути як завгодно великим із як завгодно дорогим конструктором копіювання, тому вам слід використовувати const T& у загальному коді.
модель void Print(const T&obj);Однак це погіршує ситуацію для малих і дешевих типів, що є прикро. Це також не те, що компілятор може виправити за допомогою оптимізації, тому що сигнатура функції та умова виклику є частиною - ось наша улюблена абревіатура з трьох літер - ABI. У найкращому випадку компілятор може включити його та виключити весь виклик.
Є способи обійти це, бо, звичайно, вони є, але це працює™ у Carbon, і це добре.
Але справжня причина, чому я в захваті від цієї функції, не пов’язана з усуненням завантажень/зберігань пам’яті.
Перевага №3: копії, які не є копіямиЗауважте, що перетворення, яке може виконати компілятор, не зовсім те саме, що const T& -> T у C++. Останній створює копію аргументу: якщо необхідно, він викличе конструктор і деструктор копіювання.
У Carbon це не так: значення просто встановлюється на регістр. Оскільки викликана функція не викликає деструктор параметра, викликаю не потрібно викликати конструктор копіювання. Це означає, що оптимізація буде проведена навіть для вуглецевого еквівалента std::unique_ptr. там ...
![Найбільш захоплюючою особливістю Carbon є його умовність викликів](https://www.foonathan.net/images/background.jpg)
Минулого тижня Чендлер Керрут анонсував Carbon, потенційну заміну C++, над якою він працював протягом двох років. Він має звичайні круті функції, яких ви очікуєте від сучасної мови: корисні генерики, інтерфейси компілятора/риси/концепції, модулі тощо. .
Це те, про що я сам думав у минулому, і, наскільки мені відомо, ніколи раніше не робилося мовою низького рівня, але ця концепція має великий потенціал. Дозвольте мені пояснити, про що я говорю.
Передача вуглецевих параметрівЗа замовчуванням, тобто якщо ви більше нічого не пишете, параметри Carbon передаються через еквівалент const T& у C++.
бал класу { змінна x: i64; змінна y:i64; змінна z:i64; } fn Print(p: Dot); точка попадання { std::uint64_t x, y, z; }; void Print(const Point&p);Проте - і це частина імпорту - компілятору дозволено перетворити це на T згідно з правилом "як ніби".
fn Print(x: i32); void Print(std::int32_tx);... і що? Чому я так радію цьому?
Перевага №1: ПродуктивністьПропускати речі через const T& завжди добре, чи не так? Зрештою, ви уникаєте копії!
Хоча це правда, посилання по суті є покажчиками на рівні збірки. Це означає, що передача аргументу через const T& встановлює регістр на його адресу, що означає
у викликаючому аргументі потрібна адреса, і він повинен зберігатися десь у пам’яті, і у callee, параметр повинен завантажити значення з пам'яті під час його читання.Це єдині варіанти для типів, які не вміщуються в реєстр, або невеликих типів із нетривіальними конструкторами копіювання, але вони менш ідеальні для тривіально скопійованих типів, які підходять.
Порівняйте збірку між функцією add, яка отримує свої аргументи через const T&
[[gnu::noinline]] int add(const int& a, const int& b) { повернути a + b; } int foo() { повертає add(11, 42); }і той, хто цього не робить
[[gnu::noinline]] int add(int a, int b) { повернути a + b; } int foo() { повертає add(11, 42); }Усі сховища та завантаження пам’яті зникають; ви не хочете переходити за посиланням!
Тож дуже добре, що в Carbon вам не потрібно думати про це – компілятор просто зробить правильні речі за вас. Крім того, ви не завжди можете зробити це вручну.
Перевага №2: Оптимальна домовленість про виклики в загальному кодіПрипустімо, ми хочемо написати загальну функцію друку на C++. Тип може бути як завгодно великим із як завгодно дорогим конструктором копіювання, тому вам слід використовувати const T& у загальному коді.
модель void Print(const T&obj);Однак це погіршує ситуацію для малих і дешевих типів, що є прикро. Це також не те, що компілятор може виправити за допомогою оптимізації, тому що сигнатура функції та умова виклику є частиною - ось наша улюблена абревіатура з трьох літер - ABI. У найкращому випадку компілятор може включити його та виключити весь виклик.
Є способи обійти це, бо, звичайно, вони є, але це працює™ у Carbon, і це добре.
Але справжня причина, чому я в захваті від цієї функції, не пов’язана з усуненням завантажень/зберігань пам’яті.
Перевага №3: копії, які не є копіямиЗауважте, що перетворення, яке може виконати компілятор, не зовсім те саме, що const T& -> T у C++. Останній створює копію аргументу: якщо необхідно, він викличе конструктор і деструктор копіювання.
У Carbon це не так: значення просто встановлюється на регістр. Оскільки викликана функція не викликає деструктор параметра, викликаю не потрібно викликати конструктор копіювання. Це означає, що оптимізація буде проведена навіть для вуглецевого еквівалента std::unique_ptr. там ...
What's Your Reaction?
![like](https://vidianews.com/assets/img/reactions/like.png)
![dislike](https://vidianews.com/assets/img/reactions/dislike.png)
![love](https://vidianews.com/assets/img/reactions/love.png)
![funny](https://vidianews.com/assets/img/reactions/funny.png)
![angry](https://vidianews.com/assets/img/reactions/angry.png)
![sad](https://vidianews.com/assets/img/reactions/sad.png)
![wow](https://vidianews.com/assets/img/reactions/wow.png)