LINUX.ORG.RU

В C++ добавят Rust

 , , ,


2

4

Привет, ЛОР! Я тебе покушать принёс.

Опубликован черновик расширения Safe C++, представляющего собой надмножество языка с возможностью отключать в коде Undefined Behaviour и прочие небезопасные штуки. Safe C++ добавляет в язык также borrow checker, pattern matching и другие функции, знакомые и любимые программистами на Rust. unsafe блоки входят в комплект.

Пример кода:

#feature on safety
#include <std2.h>

int main() safe {
  std2::vector<int> vec { 11, 15, 20 };

  for(int x : vec) {
    // Ill-formed. mutate of vec invalidates iterator in ranged-for.
    if(x % 2)
      mut vec.push_back(x);

    std2::println(x);
  }
}

Ошибка при сборке этого кода:

$ circle iterator.cxx -I ../libsafecxx/single-header/
safety: during safety checking of int main() safe
  borrow checking: iterator.cxx:10:11
        mut vec.push_back(x);
            ^
  mutable borrow of vec between its shared borrow and its use
  loan created at iterator.cxx:7:15
    for(int x : vec) {

Чтение за пределами обычных массивов также станет невозможным:

#feature on safety
#include <cstdint>

int main() safe {
  int array[4] { 1, 2, 3, 4 };
  size_t index = 10;

  // Panic on out-of-bounds array subscript.
  int x = array[index];
}

Результат:

$ circle subscript_array.cxx
$ ./subscript_array
subscript_array.cxx:9:17
int main() safe
subscript is out-of-range of type int[4]
Aborted (core dumped)

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

Ссылка: https://safecpp.org/draft.html

★★★★★

Последнее исправление: hateyoufeel (всего исправлений: 2)

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

При этом на нативный Rust переписывают с такой скоростью

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от anonymous

ну это только демки писать. гуй начального уровня. на плюсах таких поделий - не счесть.

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

kvpfs_2
()
Ответ на: комментарий от alysnix

ну это только демки писать. гуй начального уровня. на плюсах таких поделий - не счесть.

Это полноценный гуй с аппаратным ускорением, виджетами и прочей сранью. На нем COSMIC написали.

и кстати хорошо бы приличную ide-шку

VSCode + LSP, NeoVIM + LSP, Emacs + LSP.

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

VSCode + LSP, NeoVIM + LSP, Emacs + LSP.

vscode - это javascript

neovim - си + луа

emacs - си + лисп

то есть в их реализации руст участия не принимал.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от anonymous

Это полноценный гуй с аппаратным ускорением

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

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

Примеры такого можно увидеть?

Ну посмотри на тот же Frama C. По сути, тебе нужно доказать, что индексы никогда не выйдут за пределы размеров массива, что делается относительно просто. Кажется, даже ПиВаС студио от Лысого такое мог.

Во влажных мечтах.

Есличо, по ссылке в посте есть ссылки на godbolt для их кода. Т.е. прототип уже есть.

Выходит, твой аргумент тут в том, что средний программист на C++ – тупой мудак и будет делать убогий говнокод, не потрудившись даже потрогать профайлер и посмотреть, действительно ли у него тормозит там где он думает (почти всегда тормозит где-то в другом месте).

Нет, я такого не говорил.

Но вот как события будут развиваться: народ быстро обнаружит, что operator[] дает оверхэд, а какой-нибудь новый unsafe_at – нет. И начнет фигачить повсюду unsafe_at вместо operator[].

Правильно, ты такое написал. Цитируя @Sun-ch: "Для таких на ручных гранатах пишут «В рот не класть!»

Я бы вообще хотел, чтобы C++ применялся реже, а писало бы на нем меньше народу.

Да, мы все хотим, чтобы этот монстр уже сдох наконец.

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

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

у сапожника должны быть свои сапоги, а не китайские кеды.

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

Зачем писать VSCode и Neovim заново, они уже есть.

ты ваще что-ли? они же ненадежны(js и си)! они могут упасть и испортить праздник. а руст надежен! - это же генеральная мысль руста.

то есть руст грозится все переписать самым надежным образом. а как ты победишь си++ например, если не перепишешь все с него на руст?

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

Что это? Я вижу 5к строк сишного кода в отвратительном стиле. Не вижу результатов аудита. Не вижу чтобы твоя либа была в репозиториях популярных дистрибутивов. Просто куча кода, которая что-то делает.

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

ты ваще что-ли? они же ненадежны(js и си)! они могут упасть и испортить праздник. а руст надежен! - это же генеральная мысль руста.

Какое отношение это имеет к текстовому редактору?

то есть руст грозится все переписать самым надежным образом

Ты разговариваешь с языком программирования? Давно?

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

в слове психиатр нет буквы О! и ваще - только психи знают всех хороших психиатров. а я с психами стараюсь дела не иметь.

Ты из тех людей у кого в друзьях только два алкаша из детства и коллеги?

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

Они, типа, не сидят на работе 24/7

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

короче - правильно что не сидят, а то к доктору попадут. вам посоветовать хорошего терапевта по сидницам?

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

Правильно, ты такое написал.

Да, такое. Никого не считал и не называл тупым мудаком.

Да, мы все хотим, чтобы этот монстр уже сдох наконец.

Я хз кто это «вы все» и что вы хотите, но у меня нет желания, чтоб C++ сдох.

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

Ищи RCE или ещё какую уязвимость, либо нечего было про код спрашивать.

Я спрашивал пруфы, а не пять тыщ всратого сишного кода. Заниматься аудитом твоего поделия я не собираюсь. Доказательств качества принесенного у тебя нет. Как и истории найденных багов. Так что сорян, не засчитывается. Даже эту не самую большую кодовую базу могли пятнадцать лет вылизывать от сотен UAF и off-by-one.

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

Но вот как события будут развиваться: народ быстро обнаружит, что operator[] дает оверхэд, а какой-нибудь новый unsafe_at – нет. И начнет фигачить повсюду unsafe_at вместо operator[].

Никого не считал и не называл тупым мудаком.

these_are_the_same_picture.jpg

Хотя я не видел, чтобы народ повсюду херачил reinterpret_cast вместо static_ или dynamic_. Так что наверное не всё настолько плохо.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

these_are_the_same_picture.jpg

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

Я работал со вчерашними студентами, которым никто не рассказывал про то, как можно писать на C++ нормально, сводя риск отстрела ног к минимуму. И им не рассказывали о том, что же лежит под капотом у тех же стандартных контейнеров, чтобы понимали какие накладные расходы связаны с тем же std::vector.

Они не тупые и не мудаки, их просто еще не научили.

Я работал с людьми, которые дофига знали и умели в своей прикладной области, но для которых C++ был просто еще одним языком. И которые, как и студенты выше, просто никогда не обучались правильному обращению с языком.

Они не тупые и не мудаки, им просто понадобилось какое-то подмножество C++.

Хотя я не видел, чтобы народ повсюду херачил reinterpret_cast вместо static_ или dynamic_

Нередко тупо херачат приведение в стиле Си.

Причем особо это доставляет, когда такие приведения (вместо static_cast-ов) используют в пропозалах для развития C++.

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

Я работал со вчерашними студентами, которым никто не рассказывал про то, как можно писать на C++ нормально, сводя риск отстрела ног к минимуму. И им не рассказывали о том, что же лежит под капотом у тех же стандартных контейнеров, чтобы понимали какие накладные расходы связаны с тем же std::vector.

Я не понимаю. Ты пытаешься отстаивать мой аргумент за меня тут, что ли? Тем более надо проверок насовать по умолчанию!

Они не тупые и не мудаки, их просто еще не научили.

Но код они пишут, не глядя в документацию к языку? У меня при виде кода, написанного такими пациентами, обычно именно эти два слова в голове вертятся.

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

Я не понимаю. Ты пытаешься отстаивать мой аргумент за меня тут, что ли?

Как я уже сказал, я совсем не против того, чтобы сделали проверки по умолчанию. Просто думаю, что за весьма короткое время большая часть C++ разработчиков начнут по умолчанию использовать те методы, которые без проверок. И мы окажемся там же, где и сейчас – есть метод at, но по умолчанию широко используется именно operator[].

Но код они пишут, не глядя в документацию к языку?

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

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

Просто думаю, что за весьма короткое время большая часть C++ разработчиков начнут по умолчанию использовать те методы, которые без проверок. И мы окажемся там же, где и сейчас – есть метод at, но по умолчанию широко используется именно operator[].

Это если останется все как есть, если же предложенный safe внедрят то скорее всего уже придется делать лишнее движение писать unsafe и лень победит. В том же rust же поэтому get_unchecked не вытеснил [].

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

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

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

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

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

Так они и в «типа безопасном» C++ продолжат так же. Узнают однажды, что operator[] типа медленный и будут херачить то, что считается быстрым.

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

  • полагаться на какие-то умные статистические анализаторы;
  • писать на DSL-ях и делать трансляцию в заведомо корректный C++ный код.

Что-то еще?

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

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

Так они и в «типа безопасном» C++ продолжат так же. Узнают однажды, что operator[] типа медленный и будут херачить то, что считается быстрым.

Откуда они это узнают? Для этого надо читать уметь, а твои чукчи явно писатели.

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

Откуда они это узнают?

Из Интернета, скорее всего.

Приведу пример немного из другой оперы, но так же касательно C++.

Есть в C++ такая де-факто стандартная штука, как CMake. Вроде как даже сейчас можно писать хорошие, т.н. «modern CMake» описания проектов, в которых все по рекомендациям лучших собаководов и т.д., и т.п.

Одна проблема: мало кто знает и умеет в этот самый «modern CMake». А с учетом того, какая это угребищная система вообще, то некоторые (включая меня самого) предпочитают не тыкать это говно говна даже трехметровой палкой.

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

Как это делается?

Просто ищется что-то похожее в Интернете, вставляется, пробуется. Если работает, то остается.

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

Те же люди, которым повезло освоить «modern CMake» наверняка будут смотреть на таких как я как на «тупых мудаков», которые не взяли на себя труд досканально изучить инструмент, с которым им приходится работать.

Вот так же и с C++. Нужно кому-то что-то сделать, находится в Интернете первый работающий рецепт и все.

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от eao197

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

не надо проверять индекс на каждое обращение к массиву, если это возможно.

проверьте начальное и конечное значение индекса, а потом молотите без проверок внутри этого интервала. в 90 процентов случаев этого достаточно.

оператор [] с внутренней проверкой это очевидно для рандомного доступа, а не последовательного как в for (….) например.

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

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

Для вот этой вот срани C++ вообще не нужен,
Хуже того, это в лёгкую делается на пердоне с numpy.

Чу-у-у-ува-а-а-ак!!! Я столько лет тебя жду!! Помоги, братан!!

Вот пердон с нумпаем:

import numpy as np 
import imageio as iio
import time

def main():
    img = iio.v3.imread('file.png')

    total = 0
    h, w, n = img.shape

    t1 = time.process_time()

    for i in range(h):
        for j in range(w):
            r = np.int64(img[i, j, 0] )
            g = np.int64(img[i, j, 1] )
            b = np.int64(img[i, j, 2] )
            total += r + g + b

    average = total / ( h * w)
    t2 = time.process_time()
    print(f"CPU time: {t2 - t1:.2f} seconds")
    print(f"Average bit per pixel: {average:.2f}")
    print()

main()

Вот баганутая говносишечка с ввыходом за границы массива:

struct img
{
    size_t width;
    size_t height;
    unsigned char *data;
};


static void read_png(struct img *img, const char *file_name)
{
    ...
}

int main(int argc, char *argv[])
{
    uint64_t start;
    uint64_t end;
    struct timespec ts;
    uint64_t total = 0;
    double average;
    double time;
    struct img img = {0};

    read_png(&img, "file.png");

    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
    start = ts.tv_sec * 1000000000 + ts.tv_nsec;

    for(uint64_t y = 0; y < img.height; y++)
    {
        for(uint64_t x = 0; x < img.width; x++)
        {
            unsigned char *p = img.data + img.width*3*y + x*3;
            total += p[0] + p[1] + p[2];
        }
    }

    average = total;
    average /= img.width * img.height;

    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
    end = ts.tv_sec * 1000000000 + ts.tv_nsec;
    time = end - start;
    time /= 1000000000;

    printf("CPU time: %.2f seconds\n", time );
    printf("Average bit per pixel: %.2f\n", average);
    printf("\n");

    return 0;
}

Вот результаты прогона на простеньком png 10К на 10К:

user@computer:/tmp$ python3 python.py
/tmp/testnumpy/lib/python3.11/site-packages/PIL/Image.py:3368: DecompressionBombWarning: Image size (100000000 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
  warnings.warn(
CPU time: 233.56 seconds
Average bit per pixel: 65.88

user@computer:/tmp$ ./cprogram
CPU time: 0.23 seconds
Average bit per pixel: 65.88

user@computer:/tmp$ 

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

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk
    for i in range(h):
        for j in range(w):
            r = np.int64(img[i, j, 0] )
            g = np.int64(img[i, j, 1] )
            b = np.int64(img[i, j, 2] )
            total += r + g + b

Оправдываешь ник. Я не использовал numpy, подозреваю в твоем случае это должно быть просто total = numpy.sum(img), циклы в питоне медленные, или используй ускорение для циклов например numba, тогда сможешь продолжать писать в своем стиле 60х годов.

MOPKOBKA ★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 3)
Ответ на: комментарий от LamerOk

заменяешь циклы на average = np.mean(np.int64(img[:, :, 0])+np.int64(img[:,:, 1])+np.int64(img[:, :, 2])) и питон совокупно победит, даже без нумбы, при том что сишная портянка даже не вся приведена

zurg
()
Последнее исправление: zurg (всего исправлений: 1)
Ответ на: комментарий от LamerOk

твой си код офигенен. ты просто считаешь среднее от картинки?

рассматривай картинку его не как двумерный, а как одномерный массив. и одним циклом делай все.

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от zurg

питон совокупно победит

не победит. все что может сделать питон - вызвать встроенную нативную процедуру, что писана на си, что будет считать среднее.

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

уже же победил, питоновское сильно короче, читаемее, надёжнее и по времени того же порядка(с моей заменой)

вызвать встроенную нативную процедуру, что писана на си

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

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

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

zurg
()
Последнее исправление: zurg (всего исправлений: 2)
Ответ на: комментарий от zurg

уж стопицот раз в инете сравнивали нумпай с си и плюсами, и везде последние выигрывали.

естессно, если правильно писать алгоритмы и компилировать с правильной оптимизацией.

тут с оговоркой, что нумпай может эксплуатировать simd инструкции. но с++ тоже это может

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)