Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Питекантроп
246 / 140 / 6
Регистрация: 14.06.2010
Сообщений: 340
#1

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

21.12.2011, 18:28. Просмотров 738. Ответов 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 компилирует, но выдает неправильный результат (т.к. созданный локально стековый объект удаляется)

В чем же причина? Различные стандарты с++?
Или дело в неопределенном поведении, как, например, в таком случае?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.12.2011, 18:28
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Различия компиляторов. В чем причина? (C++):

В чем различия C# и C++ и что лучше учить? - C++
Здравствуйте! Скажите, какая существует разница между вышеупомянутыми языками? и какой из них выбрать для изучения?

В чем причина? - C++
#include &lt;windows.h&gt; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE...

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

В чем причина - C++
В общем сам код: #include&lt;iostream&gt; using namespace std; int b=20; int *a = &amp;b; int main() {

Незнаю в чем причина - C++
Программа простая вы вводите элементы массива она проверяет если этот элемент больше 0 вводит его в другой массив тоже(в массиве y толжны...

В чем причина ошибки? - C++
Код int main() { char arr; scanf(&quot;%s %s&quot;, &amp;arr, &amp;arr); printf(&quot;%s\n\n&quot;, arr);

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Kastaneda
Форумчанин
Эксперт С++
4652 / 2860 / 228
Регистрация: 12.12.2009
Сообщений: 7,268
Записей в блоге: 2
Завершенные тесты: 1
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) документируют подобные моменты, возможно об этом тоже написанно, да кто бы ее (документацию) читал
Питекантроп
246 / 140 / 6
Регистрация: 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);
                .......
}
компилируется без ошибок и предупреждений.
DU
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
22.12.2011, 00:57 #4
конструктор копирования с неконстантной ссылкой - это разрешено. вспоминаем стандартный auto_ptr, у которого конструктор копирования как раз с неконстантной ссылкой. в вашем же случае возможно ругань из-за того, что в вызывается конструктор копирования и ему передается неконстантная ссылка на временный объект. а вот это уже не очень то и разрешено. но студия умалчивает о таких ошибках.

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

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

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

подскажите в чем причина.... - C++
както все нетак... #include &lt;iostream&gt; using namespace std; int main(void) { for (int i = 0; i &lt; 3; i++) { cout &lt;&lt;...

В чем причина ошибки? - C++
помогите разобраться почему выходит ошибка? #include &lt;iostream.h&gt; #include &lt;string.h&gt; #include &lt;conio.h&gt; #include &lt;stdio.h&gt; ...

В чем различия между модульным, процедурным и структурным программированием? - C++
Доброго всем времени суток. Объясните, пожалуйста, в чем различия между модульным, процедурным и структурным программированием? Читаю в...

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


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
22.12.2011, 04:01
Ответ Создать тему
Опции темы

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