The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Вариант для распечатки  
Пред. тема | След. тема 
Форум Разговоры, обсуждение новостей
Режим отображения отдельной подветви беседы [ Отслеживать ]

Оглавление

Первый стабильный релиз компоновщика Mold, развиваемого разработчиком LLVM lld, opennews (??), 16-Дек-21, (0) [смотреть все]

Сообщения [Сортировка по времени | RSS]


68. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от n00by (ok), 17-Дек-21, 08:11 
>>печально
> Да, жаль, что не на Си.

Ну почему же

std::string get_realpath(std::string_view path) {
  char buf[8192];
  if (!realpath(std::string(path).c_str(), buf))
    return std::string(path);
  return buf;
}

Ответить | Правка | К родителю #6 | Наверх | Cообщить модератору

93. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (-), 17-Дек-21, 19:08 
> Ну почему же
> std::string get_realpath(std::string_view path) {
>   char buf[8192];
>   return buf;

Тут "спрятанно" какое-то копирование buf в возвращаемый std::string (которого не будет в си)?

Ответить | Правка | Наверх | Cообщить модератору

95. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (65), 17-Дек-21, 19:40 
Да, будет копирование. Но его можно было бы избежать, сделав buf изначально типа std::string и передавая buf.data() в realpath().

Но это всё такое крохоборство походу. В Java и Python строки неизменяемые, там любое изменение строковой переменной это создание нового строкового объекта, ещё дороже получается. Программисты на других языках смотрят на этот подсчёт крох со смехом.

Ответить | Правка | Наверх | Cообщить модератору

98. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (-), 17-Дек-21, 20:33 
> В Java и Python строки неизменяемые, там любое изменение строковой переменной это создание нового строкового объекта, ещё дороже получается.

Вообще-то, еще во втором питоне для "объемной" работы со строками были MutableString и StringIO, в Java - тот же StringBuffer.


Ответить | Правка | Наверх | Cообщить модератору

100. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (65), 17-Дек-21, 21:05 
Это всё так, но мы друг другу не противоречим. MutableString, StringIO и StringBuffer - это не строковые переменные. Это объекты, содержащие массивы байтов. В них надо загонять текстовые данные, копированием, а потом полученные строки в строковые переменные извлекать, тоже копированием. Двойное копирование то бишь. В С++ тоже такое есть, называется std::stringstream.

Ответить | Правка | Наверх | Cообщить модератору

96. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (65), 17-Дек-21, 19:52 
> копирование ... которого не будет в си

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

Это вообще распространённая проблема в С. Ошиблись при работе с памятью, потом из неправильного места в памяти читаем мусор и радостно исполняемся некоторое время, пока проблема не всплывёт вообще в другом месте кода. Трудно дебажить такое. В С++ такие ошибки встречаются гораздо реже.

Ответить | Правка | К родителю #93 | Наверх | Cообщить модератору

97. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (-), 17-Дек-21, 20:17 
>> копирование ... которого не будет в си
> А в С был бы возврат указателя на локальный буфер в функции,
> где после выхода из функции и вызова парочки других функций,

Я в курсе, потому и спросил.
>  Зато без копирования, да.

Угу, зато есть такие вот неявные кунстштюки, вместо (условного) return str::string(buf).

Ответить | Правка | Наверх | Cообщить модератору

99. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (65), 17-Дек-21, 20:45 
Такое неявное конструирование объектов очень удобно. И это не является какой-то секретной фичей, это базовая фича, о которой знают все программисты С++. Можно конструировать явно, std::string(buf) является валидной конструкцией. Можно пометить конструктор как explicit, тогда неявное конструирование будет запрещено.

А в функциональных языках вообще return неявный, возвращается последнее вычисленное выражение, тоже очень удобно, можно писать короткие функции как "a + b", без return.

Ответить | Правка | Наверх | Cообщить модератору

105. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (-), 17-Дек-21, 22:04 
> Такое неявное конструирование объектов очень удобно. И это не является какой-то секретной
> фичей, это базовая фича, о которой знают все программисты С++.

(Не)явное удобство явно переоцененно, но это вкусовщина, о которой я не вижу смысла спорить.

> А в функциональных языках вообще return неявный, возвращается последнее вычисленное выражение,

Не соглашусь. Это - игра словами (просто потому что нет ключевого слова return).
Основной момент: там, где нет return и возвращается последнее выражение - все вполне себе явно. Тем более, функциональный стиль, сопоставление с образцом и "все есть выражение" (expression), с упрятыванием "не-выражений" с побочными эффектами - куда подальше в монады и ко, (т.е. еще и код структурированн по другому).

Для "императивных" ЯП тут вспоминается "single entry, single exit" из "древнего" "structured programming".

Неявно - это к ЯП, где возможен и явный "return foo" и возврат последнего выражения (например ruby, rust - где есть "типа фунциональщина и сбоку бантик").

Ответить | Правка | Наверх | Cообщить модератору

109. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +1 +/
Сообщение от n00by (ok), 18-Дек-21, 09:18 
>> копирование ... которого не будет в си
> А в С был бы возврат указателя на локальный буфер в функции,

Смотрим man 3 realpath

       char *realpath(const char *path, char *resolved_path);

...

       Получившееся  имя  сохраняется  в  виде  строки (с null на конце) не длиннее чем PATH_MAX байт в
       буфере, указанном в resolved_path. Конечный путь не содержит символьных ссылок и компонентов /./
       или /../.

       Если  значение  resolved_path  равно NULL, то realpath() выделяет буфер размером PATH_MAX байт с
       помощью malloc(3) для хранения полного пути и возвращает указатель  на  этот  буфер.  Вызывающий
       должен освободить буфер с помощью free(3).

Т.е. в Си убрали бы char buf[8192] и вернули указатель на кучу.

Что бы в Си++ не заниматься крохоборством с магическими числами вместо PATH_MAX, можно было конструировать std::string из аллоцированого ф-цией realpath() результата?

Ответить | Правка | К родителю #96 | Наверх | Cообщить модератору

115. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (65), 18-Дек-21, 18:54 
> Т.е. в Си убрали бы char buf[8192] и вернули указатель на кучу.

В таком случае вызывающий get_realpath() должен деаллоцировать результат с помощью free(). А что если get_realpath() вернёт не результат realpath(), a path, полученный параметром? Он то вообще непонятно где находится и как аллоцирован. Тогда мы имеем или double free, или попытку сделать free() на указатель на стеке. С сопутствующими проблемами безопасности. Значит нельзя просто возвращать path, а надо сделать ему strdup(), получается одно копирование заменили на другое. Ты можешь сказать, ну тогда надо менять всю функцию, чтоб копирования не было. Или вообще её убрать и те 2-4 строчки в вызывающий код вписать. Но тогда можно и на С++ тоже функцию полностью переписать "по правильному". И вообще теряется весь предмет разговора.

> Что бы в Си++ не заниматься крохоборством с магическими числами вместо PATH_MAX, можно было конструировать std::string из аллоцированого ф-цией realpath() результата?

Да, запросто.

Ответить | Правка | Наверх | Cообщить модератору

118. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от n00by (ok), 19-Дек-21, 10:26 
>> Т.е. в Си убрали бы char buf[8192] и вернули указатель на кучу.
> В таком случае вызывающий get_realpath() должен деаллоцировать результат с помощью free().

Да. Точно так же в Си++ будет деаллоцирован буфер std:string. Только в Си все освобождения явны.

> А что если get_realpath() вернёт не результат realpath(), a path, полученный
> параметром? Он то вообще непонятно где находится и как аллоцирован. Тогда
> мы имеем или double free, или попытку сделать free() на указатель
> на стеке. С сопутствующими проблемами безопасности. Значит нельзя просто возвращать path,
> а надо сделать ему strdup(), получается одно копирование заменили на другое.
> Ты можешь сказать, ну тогда надо менять всю функцию, чтоб копирования
> не было. Или вообще её убрать и те 2-4 строчки в
> вызывающий код вписать.

Ну да, в Си эта обёртка вроде как совсем не нужна.

> Но тогда можно и на С++ тоже функцию
> полностью переписать "по правильному". И вообще теряется весь предмет разговора.

Так и я о том. Вроде как переписали на Си++, но наполовину, в итоге там потенциально буфер переполняется.

>> Что бы в Си++ не заниматься крохоборством с магическими числами вместо PATH_MAX, можно было конструировать std::string из аллоцированого ф-цией realpath() результата?
> Да, запросто.

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

Ответить | Правка | Наверх | Cообщить модератору

122. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от Аноним (65), 19-Дек-21, 20:10 
> Только в Си все освобождения явны.

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

> Вроде как переписали на Си++, но наполовину,
> в итоге там потенциально буфер переполняется.

Да, не очень хорошо получилось. Но код на стыке языков часто таким бывает. Я не про потенциальное переполнение буфера, а просто про элегантность. Да и get_realpath() - это по сути С++ wrapper вокруг сишного API realpath(), а к врапперам требования по элегантности снижены, врапперы как раз и призваны локализовать неэлегантность в себе, предоставляя удобное API наружу.

Ответить | Правка | Наверх | Cообщить модератору

129. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +/
Сообщение от n00by (ok), 20-Дек-21, 11:25 
>> Только в Си все освобождения явны.
> Хм, так пишешь, как будто это хорошо. Явны, значит замусоривают код и
> заставляют программиста всё деаллоцировать вручную, т.е. лишают автоматизации, заставляют
> следить чтобы и не забыть про деаллокацию, и чтобы она больше
> одного раза не произошла.

Так там кто-то хотел на Си, значит для него это хорошо.

>> Вроде как переписали на Си++, но наполовину,
>> в итоге там потенциально буфер переполняется.
> Да, не очень хорошо получилось. Но код на стыке языков часто таким
> бывает. Я не про потенциальное переполнение буфера, а просто про элегантность.
> Да и get_realpath() - это по сути С++ wrapper вокруг сишного
> API realpath(), а к врапперам требования по элегантности снижены, врапперы как
> раз и призваны локализовать неэлегантность в себе, предоставляя удобное API наружу.

Есть же std::filesystem::canonical().

Ответить | Правка | Наверх | Cообщить модератору

110. "Первый стабильный релиз компоновщика Mold, развиваемого разр..."  +1 +/
Сообщение от n00by (ok), 18-Дек-21, 09:21 
>> Ну почему же
>> std::string get_realpath(std::string_view path) {
>>   char buf[8192];
>>   return buf;
> Тут "спрятанно" какое-то копирование buf в возвращаемый std::string (которого не будет
> в си)?

Тут переполняется стек при "нестандартном" значении PATH_MAX.

Ответить | Правка | К родителю #93 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру