Ошибки, баги, вопросы - страница 3478

 
Vladimir Simakov #:

Это не баг, это операторы разные.

Утверждаете, что эти два оператора не являются завуалированными методами? Где почитать про это?

 
Cуществует простое доказательство на базе MQL, что && не равносильно operator&& - это разный результат:
class A {
public:
    A() {}     A(const A&) {}
    A operator&&(const A&) { Print(3); return this; }
    A operator||(const A&) { Print(4); return this; } 
};
A f( int i ) { Print( i ); return A(); }
void OnStart()
{                                           //Результат:
    f(1)         || f(2)          && f(5);  //5-2-3-1-4
    f(1).operator||(f(2)).operator&&(f(5)); //5-2-1-4-3
}
 

A100 # :
Cуществует простое доказательство на базе MQL, что && не равносильно operator&& - это разный результат:

Вы должны быть честными с приоритетом.

//Результат:
  (f(1)        || f(2))         && f(5);  //5-2-1-4-3
  f(1).operator||(f(2)).operator&&(f(5)); //5-2-1-4-3
 
Alain Verleyen #:

Вы должны быть честными с приоритетом.

Задача была доказать, что && не равносильно operator && (|| не равносильно  operator||) - здесь и далее - речь о перегруженных операторах в разной записи

class A {
public:
    A() {}     A(const A&) {}
    A operator&&(const A&) { Print(3); return this; }
    A operator||(const A&) { Print(4); return this; }
    A operator88(const A&) { Print(3); return this; }
    A operator11(const A&) { Print(4); return this; }
};
A f( int i ) { Print( i ); return A(); }
void OnStart()
{                                           //Результат:
    f(1)         || f(2)          && f(5);  //5-2-3-1-4
    f(1).operator||(f(2)).operator&&(f(5)); //5-2-1-4-3
    f(1).operator11(f(2)).operator88(f(5)); //5-2-1-4-3
}

operator&& ведет себя не как &&, а как функция operator88

А то, что свою роль в этом сыграл приоритет - так это только усиливает доказательство - причина не важна, важен результат. По крайней мере Вы признали, что приоритет все-таки действует на && и не действует на operator&&

Если бы && (||) была бы обычной функцией, то результат был бы одинаковым, а он - разный

А если приоритет сохранился, то почему остальное не может сохранится (кроме ленивости конечно - она принципиально невозможна)

Опять же - не на пустом месте это отменили (until C++17)
 
Alain Verleyen #:

Вы должны быть честными с приоритетом.

Для полноты доказательства, что перегруженный оператор не равносилен методу\функции - возьмем операторы с одинаковым приоритетом:

class A {
public:
    A() {}     A(const A&) {}
    A operator+=(const A&) { Print(3); return this; }
    A operator-=(const A&) { Print(4); return this; }
};
A f( int i ) { Print( i ); return A(); }
void OnStart()
{                                           //Результат:
    f(1)         += f(2)          -= f(5);  //5-2-4-1-3
    f(1).operator+=(f(2)).operator-=(f(5)); //5-2-1-3-4
}
Результат все-равно - разный. Доказательство завершено!
 
A100 # :

Для полноты доказательства, что перегруженный оператор не равносилен методу\функции - возьмем операторы с одинаковым приоритетом:

Результат все-равно - разный. Доказательство завершено!

Доказательство чего? Проверьте, что это дает на C++!

А вы продолжаете сравнивать то, что не сравнимо!

    f(1)         += f(2)         -= f(5);   //5-2-4-1-3   Evaluated from right to left
    f(1).operator+=(f(2).operator-=(f(5))); //5-2-4-1-3   Evaluated from left to right as functions, it needs correct ()

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

 
fxsaber #:

Утверждаете, что эти два оператора не являются завуалированными методами? Где почитать про это?

https://en.cppreference.com/w/cpp/language/operators

Welcome)))

 
Alain Verleyen #:

Доказательство чего? Проверьте, что это дает на C++!

А вы продолжаете сравнивать то, что не сравнимо!

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

Доказательство того, что выделено фиолетовым в Википедии: перегрузка операторов не меняет их приоритет и ассоциативность

На С++ результат как выяснилось зависит от компилятора этот получен на C++20 Shell 

 
Ошибка при выполнении:
//Test2.mq5
#property library
    void f2(       string ) export {}
//Test.mq5
#import "Test2.ex5"
    void f2( const string = "2" );
#import
    void f1(       string )        {}
    void f1( const string = "1" );
void OnStart()
{
    f1(); //(1)//нормально
    f2(); //(2)//Error: cannot find 'f2' in 'Test2.ex5'
}

А какая принципиальная разница между (1) и (2) ?

 

Кончайте уже причиндаламаи меряться)))

https://en.cppreference.com/w/cpp/language/operator_precedence

https://en.cppreference.com/w/cpp/language/operators

https://en.cppreference.com/w/cpp/language/eval_order

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

PS/ В С++ нельзя полагаться на тест поведения, сделанный на компиляторе. Даже если все компиляторы, доступные вам показали идентичное поведение. А потом, вы, решив супер-пупер ускорить свой код, засунули его в, например,  icc с ключом /Oipo и сильно прихренели от изменившегося поведения (а вот это уже из реального опыта, после этого всем коллективом, пару-тройку недель, выпиливали UB из десятилетнего легаси, пока не добились детерминированного результата).

PSS. И я не просто так всегда топлю за недопустимость вот такого:

union U
{
    uint64_t a;
    double b;
};

void Foo(double a)
{
    // Do something
}

int main()
{
    U a;
    uint64_t b = 100500;
    a.a = 100500;
    Foo(a.b);
    Foo(reinterpret_cast<double&>(b));
}

,хотя прекрасно знаю, что и msvs и gcc абсолютно ожидаемо это обрабатывают, вот только с точки зрения стандарта С++, в обоих случаях UB. Кстати, в случае с С, фишка с union законна.