LINUX.ORG.RU

GSoap и современный C++

 , gsoap,


0

3

Реально эту штуку заставить генерировать код хотя бы на C++11 чтобы не void*, а std::unique_ptr и так далее было? Ну и хоть кто-то по-человечески с объявлением функций, дабы это всё не выглядело как обертка на С.

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

По этому поводу могу только повториться:

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

Соответственно можно вызывать drop в ветке else для if’а в котором принимается решение. Но если оптимизатор решил, что лучше сделать по-другому - ему виднее. Может быть это сделано принципиально по-другому в силу особенностей llvm, всё-таки у раста простор для оптимизаций ещё большой. Подробностей я не знаю. Но потенциально это можно делать без доп. флагов, т.к. объект после перемещения использован не будет.

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

https://godbolt.org/z/fY1snY4Y5

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

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

в плюсах ручное управление памятью. я вообще не обязан, что либо уничтожать

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

а счетчики ссылок это для автоматического управления.

Да. И в расте они нужны ровно в тех же случаях, что и в плюсах. Рубль в рубль.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt
{
  some_class v(10);
  return v.some_fun();
}
{
  let v = SomeClass::new(10);
  return v.some_func()
}

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

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

это вообще разный код.

код на с++ аналогичный растовому писался бы так

{
  auto v = SomeClass::create(10);
}

так что давай нарисуй inplace конструирование на расте обьявленной переменной на стеке.

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

В плюсах

some_class v(10);

и

auto v = SomeClass(10);

делают абсолютно одно и тоже. Это просто разные формы записи одного и того же кода. Если SomeClass::create будет идентичен конструктору, то и

auto v = SomeClass::create(10);

будет делать ровно тоже самое.

И точно так же и в расте. Там тоже есть rvo. И при вызове

let v = SomeClass::new(10);

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

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

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

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

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

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

то есть вызов дропа нельзя делать безусловно.

пример твой мне неопонятен. галиматья какая то.

просто напиши функцию A, что забирает обьект(у которого определен дроп) и вызови ее на условном участке в функции B. и смотри - как будет вызван дроп на обьект в этой B. и нет ли там у обьекта некоего признака перемещения.

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

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

В rust создается такой флажок в ветвлениях при необходимости. Только надо заметить, что это 2% вариантов использования. В остальных 98% такой флажок не нужен, и соответственно, не создается.

В том примере return не обязателен. Rust - это все-таки полу-функциональщина, местами там даже очень много из мира ФП. Потому многие хаскелисты обожают rust, не все, но многие. Вон, тот же товарищ Снойман, создатель stack.

Сейчас модно делать языки expression-oriented, а не statement-oriented. Statement-oriented - это прошлый век. Даже в котлине - expression-oriented.

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

И тут надо понимать, что флажок этот сидит не в самом объекте - это всего лишь деталь реализации кого-нибудь блока. В теле блока на стеке он и сидит. В самом объекте никаких таких флажков нет - и не надо!

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

делают абсолютно одно и тоже.

ну ты васян ваще.

auto v = SomeClass::create(10);

в с++ это присваивание. тут вызывается конструктор копии. написано во всех учебниках. которые ты не читал.

а конструктор копии может иметь вообще произвольную семантику. он может что хошь присвоить. это просто ДРУГОЙ конструктор. он другой, а не те, что inplace.

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

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

Ага, и компилятор в годболте тоже несёт чушь.

а понять статически, где оно заканчивается невозможно.

можно!!, енжой аффиные типы.

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

а вот если сделать так

pub fn fun(fl:bool)  {
    let s = Box::new(S(777));
    if fl { 
        use_s(s);
    }
    s.p();
}

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

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

В rust создается такой флажок в ветвлениях при необходимости. Только надо заметить, что это 2% вариантов использования. В остальных 98% такой флажок не нужен, и соответственно, не создается.

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

это правильно.

а ваня_grt - васян, что сыпет ерунду направо-налево.

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

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

одно противоречит вроде другому.

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

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

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

Не хотел это писать, но ведь вынуждаешь

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

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

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

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

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

так и про перемещение поймешь когда нить.

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

тут вызывается конструктор копии

Лол. Если бы тут и вызывался конструктор, то в первую очередь перемещения, т.к. временный объект. А конструктор копирования только в случае отсутствия конструктора перемещения.

Но он тут не вызывается. Чтобы понять это тебе нужно по-лучше ознакомиться с C++. А Васян из нас, конечно же я, да.

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

а как до «семантики перемещения» жили - не подскажешь?

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

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

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

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

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

а до того, как придумали перемещение?

Ну я, естественно, говорю о современных плюсах. В 98-ом или вообще до стандартов там действительно вызывался бы конструктор копирования. Но кого это интересует, кроме археологов и шизов? Тем более когда мы ведём сравнение с растом. В общем по-изучай всё-таки плюсы, прежде чем о них рассуждать.

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

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

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

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

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

ой нашел!

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

короче ты специалист по расту еще тот. все вопросы к тебе по расту снимаются.

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

Ага, это - одна из разновидностей copy elision.

Я подозреваю, что компилятор C++ ему в коде очень много где вставляет эту самую семантику перемещения - просто человек может не подозревать об этом.

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

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

а писал то ты зачем?

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

что компилятор C++ ему в коде очень много где вставляет эту самую семантику перемещения

Семантику перемещения он вставляет только там, где есть rvalue и у типа есть конструктор/оператор перемещения. Тут всё вполне однозначно.

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

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

Я подозреваю, что компилятор C++ ему в коде очень много где вставляет эту самую семантику перемещения - просто человек может не подозревать об этом.

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

короче, это не так уж и принципиально.

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

а писал то ты зачем?

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

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

Затем, что ты написал настолько херню,

вань. а это не должно тебя волновать.

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

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

но мало кому интересно, это вообще никому не интересно, и это никак не помогает вопросу о расте.

пичалька, правда?

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

Нет.

на нет и суда нет, вань. а почему нет? что мешает?

смотри сюда

{
...
  TT xx(100);
  some_fun(xx); ///тут подставляется по значению.
  /// тут конец блока и счас обьект xx умрет.
}

что мешает его мувить в some_fun?

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

Уверен, Васян?

#include <iostream>

struct MyClass {
    MyClass()
        { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    MyClass(const MyClass &)
        { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    ~MyClass()
        { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    MyClass &operator=(const MyClass &)
        { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }

    static MyClass create() { return {}; }
};


int main() {
    auto v = MyClass::create();
}
MyClass::MyClass()
MyClass::~MyClass()

https://godbolt.org/z/6EjhqrYP1

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

а это не должно тебя волновать.

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

или очень ограниченная семантика правил

А кто, кроме тебя, говорил о том, что там не ограниченная семантика правил? Я может что-то упустил? Или вас там просто несколько?

но мало кому интересно, это вообще никому не интересно, и это никак не помогает вопросу о расте.

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

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

Я и не обещал этого делать. Этот вопрос возник по ходу диалога, а не был основополагающим.

Потенциально можно сделать без доп. флагов. Как и почему это сделано в rustc/llvm я не знаю. И в любом случае, если даже там появляется в каких-то случаях флаг, он вряд ли покидает регистры проца и на производительности не сказывается никак. Неизмеримо. Так что тема, конечно, интересная, но не настолько, чтобы её серьёзно копать.

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

Стандарт. Конструктор/оператор перемещения вызывается только для rvalue. Тут не rvalue. Есть, конечно, as if rule, но конструкторы/операторы перемещения в плюсах ничем не ограничены, так что я сомневаюсь, что его тут когда-нибудь удастся применять. По факту там простое разрешение перегруженных функций, и по правилам этого разрешения тут будет вызван конструктор копирования.

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

Потенциально можно сделать без доп. флагов. Как и почему это сделано в rustc/llvm я не знаю. И в любом случае, если даже там появляется в каких-то случаях флаг,…

ты все таки определись со внутренней логикой это фразы.

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

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

Там флажок в rust ограниченного применения.

Да я-то не против, вполне готов в это поверить. А ты, кстати, не в курсе почему так сделано, а не просто дроп объекта сразу после условия, если оно не сработало? Так вроде бы логичнее и без флагов.

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

Ну, здесь зато важно, есть у конструктора перемещения noexcept или нет. Если есть, то при включенной опции поддержки исключений, компилятор C++ создаст сначала копию объекта через конструктор копирования, а потом уже копию передаст конструктору перемещения. Отсюда и тормоза. А это нужно для выполнения самой строгой гарантии безопасности - атомарности действия.

Вот, понимаешь, такие нюансы так подбешивают порой. А вот на rust голова гораздо реже думает о таких мелочах. Там много-много проще писать код - больше думаешь о самой задаче.

Так что, ты все-таки прислушайся к моему совету. Изучи раст! Рекомендую книгу от O’Reilly. Есть русский перевод

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

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

Ну во-первых, я действительно не знаю. Во-вторых, с чего ты взял, что это простой вопрос? В третьих, предполагаю, что это особенности оптимизатора llvm. Он всё-таки для плюсов в первую очередь создавался и у раста с ним бывали сложности.

А может быть это просто не имеет смысла и через доп. флаг делать банально быстрее.

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

это вопрос не llvm. это вопрос реализации семантики перемещения этого вашего раста(которой он особо гордится).

И все, кто вопиет, что я Раста не знаю(а он мне вообщем-то и не нужен), сами не знают, как это будет реализовано в коде.

То есть они просто веруют растовым евангелистам. И не знают, что и сколько стоит внутри растового бинарника.

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

Во-вторых, с чего ты взял, что это простой вопрос?

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

и как это обеспечено.

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

и никто пока обратного не доказал.

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

это вопрос не llvm.

Это как раз вопрос llvm, а конкретно его оптимизатора. С семантикой перемещения раста как раз всё понятно. Деструктор будет вызван после последнего использования до выхода из блока.

А вот куда когда и как раскидает вызовы оптимизатор вполне может зависеть от реализации и версии. И если оптимизатор посчитает нужным, он вполне может и доп. флаги вводить и код переписывать. Ровно так же, как в сишке и плюсах.

сами не знают, как это будет реализовано в коде

А ты про сишку или плюсы знаешь, как будет реализовано в коде? Не глядя в выхлоп компилятора?

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

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

Нельзя. Компилятор не скомпилирует. Уж сколько раз тебе об этом говорили.

Если не веришь, открой godbolt и убедись сам, в чём проблема?

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

Ну я тебе говорил способ это сделать. Дальше уже твоё дело.

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

меня от раста корежит :)

то есть такой псевдокод не компилируется?

let xx = ...

// тут 100 строк кода

if (external_cond) {
  крадем xx
}

xx = xxx;

то есть даже если «крадем_xx» под условием - xx по-любому считается украденным из блока??? и присваивание

xx = xxx

это ошибка?

Тогда это тухлая семантика. Потому что под условием. Потому что условие может никогда не случится, а обьект становится невалидным. Это трешак. Я просто не верю, что раст настолько примитивен.

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