Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
249 / 143 / 21
Регистрация: 14.06.2010
Сообщений: 340
1

Различия компиляторов. В чем причина?

21.12.2011, 18:28. Просмотров 1034. Ответов 4
Метки нет (Все метки)

есть небольшой код, который успешно компилируется в VS 2010
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
 
template <class T>
class complex
{
public:
    T re, im;
    complex(T re = 0, T im = 0)
    {
        this->re = re;
        this->im = im;
    }
    complex(complex<T> & c)
    {
        this->re = c.re;
        this->im = c.im;
    }
 
    complex<T> operator + (complex<T> & c)
    {
        return complex<T>(re + c.re,im + c.im);
    }
 
    complex<T> operator - (complex<T> & c)
    {
        return complex<T>(re - c.re,im - c.im);
    }
    complex<T> & operator = (complex<T> & c)
    {
        this->re = c.re;
        this->im = c.im;
        return *this;
    }
    complex<T> operator + (T x)
    {
        return complex<T>(re + x,im);
    }
};
 
using namespace std;
int main(int argc, char* argv[])
{
    complex<double> a(1,3), b, c;
    c = a;
    b = a + c + 10;
    cout<<b.re<<" "<<b.im<<endl;
    cin.get();
    return 0;
}
При попытке переноса его на с++ builder 2010 возникают две ошибки:
1. Компилятору не нравится конструктор копирования. Интересно, что в старом добром builder 6 такой ошибки не возникает.
2. Не нравится вызов оператора = в строке
C++
1
b = a + c + 10;
Первое устраняется удалением конструктора копирования (он тут по сути и не нужен).
Второе - в передаче параметров оператора = через стек, а не по ссылке
C++
1
complex<T> & operator = (complex<T> c)
Просмотр дизассемблированного кода дает ожидаемые результаты: в VS передает в стек указетель, а билдер - копирует туда экземпляр класса (т.е. в случае double - в 4 раза больше).
Тестировал на компиляторе g++ - ему по душе билдеровский вариант.
Еще протестировал возврат результата по ссылке в случае с оператором +.
C++
1
2
3
4
    complex<T> & operator + (complex<T> & c)
    {
        return complex<T>(re + c.re,im + c.im);
    }
Билдер в этом случае не компилирует, а VS компилирует, но выдает неправильный результат (т.к. созданный локально стековый объект удаляется)

В чем же причина? Различные стандарты с++?
Или дело в неопределенном поведении, как, например, в таком случае?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.12.2011, 18:28
Ответы с готовыми решениями:

В чём причина причина в бд или в коде?
Вывожу данные в datagridview,видны только цифры во всех таблицах.Может кто сталкивался? Испытал...

В чем различия
Есть два варианта кода. В чем функциональные различия. Проверенно что работают они по разному. 1....

в чем различия?
чем MkDir(&quot;List&quot;); отличается от CreateDir(&quot;List&quot;)

В чем различия кодов?
у меня есть цикл вывода отзывов из таблицы. Вот он: $res = mysql_query('SELECT * FROM `table`...

4
Jesus loves me
Эксперт С++
5106 / 3119 / 352
Регистрация: 12.12.2009
Сообщений: 7,890
Записей в блоге: 2
21.12.2011, 19:31 2
C++
1
2
complex(const complex<T> & c){}
complex<T> & operator = (const complex<T> & c){}
конструктор копирования по стандарту принимает константный аргумент, поэтому билдер и g++ спотыкаются об это. Студия же выкручивается доступными средствами и, наверное, это не совсем по стадарту.
Как по стандарту выглядет operator=() я к сожалению не знаю (искать лень)), но с константым аргументом у меня компилируется.

Цитата Сообщение от Питекантроп Посмотреть сообщение
В чем же причина? Различные стандарты с++?
Или дело в неопределенном поведении, как, например, в таком случае?
Не думаю, что это UB, скорее особенности реализации. Давно известно, что компиляторы MS не шибко дружны со стандартом С/С++, но тем не менее они (MS) документируют подобные моменты, возможно об этом тоже написанно, да кто бы ее (документацию) читал
1
249 / 143 / 21
Регистрация: 14.06.2010
Сообщений: 340
22.12.2011, 00:52  [ТС] 3
таки да, const исправляет положение. И билдер и g++ компилируют.
Но в некоторых случаях компилируется и без const. Например, код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class X
{
public:
    int a;
    X() { a = 0; }
    X(X & x) { a = x.a; }
};
int main(int argc, char* argv[])
{
        X z;
        X z1(z);
                .......
}
компилируется без ошибок и предупреждений.
0
DU
1492 / 1138 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
22.12.2011, 00:57 4
конструктор копирования с неконстантной ссылкой - это разрешено. вспоминаем стандартный auto_ptr, у которого конструктор копирования как раз с неконстантной ссылкой. в вашем же случае возможно ругань из-за того, что в вызывается конструктор копирования и ему передается неконстантная ссылка на временный объект. а вот это уже не очень то и разрешено. но студия умалчивает о таких ошибках.

C++
1
b = a + c + 10;
вот тут неявный каст из инта в complex<double> (т.е. создается временный объект) и он отдается оператору +, который почему-то с неконстантной ссылкой. потом еще раз зовется оператор + с предыдущей суммой, результат которой тоже во временном объекте. потом результат обеих сумм (который конечно же во временном объекте) передается в оператор =, который точно так же с неконстантной ссылкой.

все, что метод не изменяет должно передаваться по константной ссылке или же по значению. иначе интерфейс вызывает недоверие и в некоторых случаях не компилится. Эта болезнь у всех ваших операторов в исходном классе.
1
249 / 143 / 21
Регистрация: 14.06.2010
Сообщений: 340
22.12.2011, 04:01  [ТС] 5
Цитата Сообщение от DU Посмотреть сообщение
вызывается конструктор копирования и ему передается неконстантная ссылка на временный объект. а вот это уже не очень то и разрешено.
Таки да. Если передавать невременные объекты, то все работает.

Цитата Сообщение от DU Посмотреть сообщение
вот тут неявный каст из инта в complex<double>
такой каст вряд ли бы произошел неявно =)). Тут каст из инт в дабл и вызов
C++
1
complex<double> operator + (double x) {}
Впрочем, это сути не меняет. Спасибо за ответ.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.12.2011, 04:01

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

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

Per Seat and Per Server. В чем различия?
чем они различаются ? для чего вообще нужно ? что они дают ? во скока вопросов ))))

В чем различия функций gets() и gets_s()
В ходе изучения с++ столкнулся с проблемой, а именно с тем что компилятор (Visual Studio 2017) не...

VB6 и VBA: в чем их различия
в чем их различия ? (я чайник не обижайтесь...)


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.