Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не пойму,что IAR не нравится
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
WHALE
IAR выдает ошибку на такой код(упрощено до минимума)
CODE
class Base
{
public:
Base(){}
};

class Derv1:public Base
{
public:
Derv1():Base(){}
};

class TInterface
{
public:
TInterface()
{
Base* pBase =&Derv1(); /*не работает - Error[Pe158]: expression must be an lvalue or a function designator // */
}
};

int main()
{
TInterface Interface;
while(1);
}

Не понимаю смысла ругани в данном случае. MSVC 2008 ест такой код без проблем
А вот так работает
CODE
class Base
{
public:
Base(){}
};

class Derv1:public Base
{
public:
Derv1():Base(){}
};

class TInterface
{
public:
TInterface()
{

Derv1 dv1;
Base* pBase =&dv1;
}
};
//-----------------------------------------------------------------------------/
int main()
{
TInterface Interface;
while(1);
}


Какого &*% ему надо?
Сергей Борщ
Я упростил еще сильнее, gcc тоже ругается:
Код
class a
{
};

void test()
{
    a * Tmp = &a();
}

test.cpp:20:18: error: taking address of temporary [-fpermissive]
     a * Tmp = &a();
                  ^
Могу предположить, что область видимости объекта ограничена этим выражением, т.е. в конце выражения объект будет уничтожен, а указатель на него останется. Хотя у вас сообщение совсем о другом. Интересно, что скажет техподдержка?
WHALE
Цитата(Сергей Борщ @ Dec 3 2015, 11:49) *
gcc тоже ругается:
Код
class a
{
};

void test()
{
    a * Tmp = &a();
}

test.cpp:20:18: error: taking address of temporary [-fpermissive]
     a * Tmp = &a();
                  ^

Ну у вас возможно правильная ругань,т.к. действительно создается временный
объект(а он уничтожится по выходу из функции test() ) и делается попытка взять его адрес.
Интересно скомпилировать мой пример в gcc.
ViKo
В C++ не силен, но я не вижу где создаются объекты Derv1, также и a. Они, вообще, создаются?
Сергей Борщ
Цитата(WHALE @ Dec 3 2015, 10:57) *
действительно создается временный
объект(а он уничтожится по выходу из функции test()
Указатель также уничтожается при выходе из функции, так что ругань идет на то, что объект уничтожается еще до присвоения указателю. И код полностью аналогичен вашему, насколько я понимаю.
WHALE
Цитата(ViKo @ Dec 3 2015, 12:36) *
В C++ не силен, но я не вижу где создаются объекты Derv1, также и a. Они, вообще, создаются?

Я тоже не гуру, но как я понимаю выражение Base* pBase =&Derv1(); - это
1. создание объекта типа Derv1.
2. создание указателя pBase на объекты типа Base.
3.Взятие адреса объекта Derv1 и присвание его pBase.

Как-то так. 05.gif Хочу полиморфмно обращаться к объектам типа Base и их наследникам.


Цитата(Сергей Борщ @ Dec 3 2015, 12:44) *
Указатель также уничтожается при выходе из функции, так что ругань идет на то, что объект уничтожается еще до присвоения указателю. И код полностью аналогичен вашему, насколько я понимаю.

У меня указатель создается в конструкторе глобального объекта TInterface и уничтожаться он не должен.
Kabdim
В работающем вариант объект создался в стеке и наружу передали подвешеный указатель. Грабли анфас.
В неработающем варианте идея как я понимаю создать объект в куче и тогда нужно прочитать про new книжку какую или к примеру http://en.cppreference.com/w/cpp/language/new .
В С++ конструкторы не занимаются выделением памяти.
Сергей Борщ
Цитата(WHALE @ Dec 3 2015, 11:54) *
У меня указатель создается в конструкторе глобального объекта TInterface и уничтожаться он не должен.
Да ладно? У вас создвется временный объект и временный указатель. Указатель уничтожается после выхода из конструктора. Объект в работающем варианте тоже уничтожается при выходе из конструктора, в неработающем - еще до присваивания адреса указателю.
Цитата
Код
    TInterface()
    {
Base*  pBase   =&Derv1();   /*не работает - Error[Pe158]: expression must be an lvalue or a function designator  // */
    }


WHALE
Цитата(Сергей Борщ @ Dec 3 2015, 13:23) *
Да ладно? У вас создвется временный объект и временный указатель. Указатель уничтожается после выхода из конструктора. Объект в работающем варианте тоже уничтожается при выходе из конструктора, в неработающем - еще до присваивания адреса указателю.

ОК,спасибо,я понял свою ошибку.
Тогда почему так не работает?
CODE
class Base
{
public:
Base(){}
};

class Derv1:public Base
{
public:
Derv1():Base(){}
};

class TInterface
{
public:
TInterface()
{
pBase =&Derv1(); //не работает - Error[Pe158]: expression must be an lvalue or a function designator


}
private:
Base* pBase;
};

int main()
{
TInterface Interface;
while(1);
}


Сейчас-то указатель не подвешеный?

Все,понял.
Объект временный и в этом все дело.
Создавать их надо не в конструкторе,а глобально.
З.Ы new - это на ББ.
Непомнящий Евгений
Цитата(WHALE @ Dec 3 2015, 12:52) *
ОК,спасибо,я понял свою ошибку.
Тогда почему так не работает?
CODE
class Base
{
public:
Base(){}
};

class Derv1:public Base
{
public:
Derv1():Base(){}
};

class TInterface
{
public:
TInterface()
{
pBase =&Derv1(); //не работает - Error[Pe158]: expression must be an lvalue or a function designator


}
private:
Base* pBase;
};

int main()
{
TInterface Interface;
while(1);
}


Сейчас-то указатель не подвешеный?

Все,понял.
Объект временный и в этом все дело.
Создавать их надо не в конструкторе,а глобально.
З.Ы new - это на ББ.


а) MSVC имеет дофига своих особенностей и то, что он что-то съедает, ни разу не показатель.
б) вы создаете временный объект на стеке и берете его адрес. Объект будет уничтожен в конце выражения ( pBase =&Derv1(); ), указатель будет указывать на какой-то мусор в стеке
в) чтобы взять у объекта адрес, он должен быть lvalue (т.е. его можно написать слева от знака присваивания). В вашем случае это очевидно не так
WHALE
Цитата(Непомнящий Евгений @ Dec 3 2015, 14:24) *
а) MSVC имеет дофига своих особенностей и то, что он что-то съедает, ни разу не показатель.
б) вы создаете временный объект на стеке и берете его адрес. Объект будет уничтожен в конце выражения ( pBase =&Derv1(); ), указатель будет указывать на какой-то мусор в стеке
в) чтобы взять у объекта адрес, он должен быть lvalue (т.е. его можно написать слева от знака присваивания). В вашем случае это очевидно не так


Cпасибо, это я уже понял, переделал и вроде работает.
Последний вопрос,чтобы закрыть тему:

Base* pBase =&Derv1();

и Derv1 dv1;
Base* pBase =&dv1;


Это ведь по сути одно и тоже и должно когмпилироваться в одинаковый ассемблерный код?
Непомнящий Евгений
Цитата(WHALE @ Dec 7 2015, 09:37) *
Base* pBase =&Derv1();

и Derv1 dv1;
Base* pBase =&dv1;


Это ведь по сути одно и тоже и должно когмпилироваться в одинаковый ассемблерный код?


Это не одно и тоже. В первом случае у вас временный объект, который будет уничтожен в конце выражения (на точке с запятой будет вызван его деструктор). После чего pBase указывает на некий мусор.

Во втором случае dv1 живет до конца блока и деструктор будет вызван на } (или до конца программы, если это глобальная переменная)

Если деструктора нет, то код может быть одинаковый. А может и нет, если компилятор решит соптимизировать и переиспользовать место на стеке
WHALE
Спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.