реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Не пойму,что IAR не нравится, Error[Pe158]: expression must be an lvalue or a function designator
WHALE
сообщение Dec 3 2015, 06:59
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



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);
}


Какого &*% ему надо?


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 3 2015, 07:49
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Я упростил еще сильнее, gcc тоже ругается:
Код
class a
{
};

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

test.cpp:20:18: error: taking address of temporary [-fpermissive]
     a * Tmp = &a();
                  ^
Могу предположить, что область видимости объекта ограничена этим выражением, т.е. в конце выражения объект будет уничтожен, а указатель на него останется. Хотя у вас сообщение совсем о другом. Интересно, что скажет техподдержка?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
WHALE
сообщение Dec 3 2015, 07:57
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



Цитата(Сергей Борщ @ 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.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 3 2015, 08:36
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



В C++ не силен, но я не вижу где создаются объекты Derv1, также и a. Они, вообще, создаются?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 3 2015, 08:44
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
WHALE
сообщение Dec 3 2015, 08:54
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



Цитата(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 и уничтожаться он не должен.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 3 2015, 08:59
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



В работающем вариант объект создался в стеке и наружу передали подвешеный указатель. Грабли анфас.
В неработающем варианте идея как я понимаю создать объект в куче и тогда нужно прочитать про new книжку какую или к примеру http://en.cppreference.com/w/cpp/language/new .
В С++ конструкторы не занимаются выделением памяти.

Сообщение отредактировал Kabdim - Dec 3 2015, 09:01
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 3 2015, 09:23
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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




--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
WHALE
сообщение Dec 3 2015, 09:52
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



Цитата(Сергей Борщ @ 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 - это на ББ.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 3 2015, 10:24
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(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 (т.е. его можно написать слева от знака присваивания). В вашем случае это очевидно не так
Go to the top of the page
 
+Quote Post
WHALE
сообщение Dec 7 2015, 06:37
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



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


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

Base* pBase =&Derv1();

и Derv1 dv1;
Base* pBase =&dv1;


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


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 7 2015, 06:54
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(WHALE @ Dec 7 2015, 09:37) *
Base* pBase =&Derv1();

и Derv1 dv1;
Base* pBase =&dv1;


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


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

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

Если деструктора нет, то код может быть одинаковый. А может и нет, если компилятор решит соптимизировать и переиспользовать место на стеке
Go to the top of the page
 
+Quote Post
WHALE
сообщение Dec 7 2015, 09:38
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



Спасибо.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 15:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.01499 секунд с 7
ELECTRONIX ©2004-2016