|
|
  |
Не пойму,что IAR не нравится, Error[Pe158]: expression must be an lvalue or a function designator |
|
|
|
Dec 3 2015, 06:59
|

Знающий
   
Группа: Свой
Сообщений: 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
|
|
|
|
|
Dec 3 2015, 07:49
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Dec 3 2015, 07:57
|

Знающий
   
Группа: Свой
Сообщений: 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
|
|
|
|
|
Dec 3 2015, 08:54
|

Знающий
   
Группа: Свой
Сообщений: 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. Как-то так.  Хочу полиморфмно обращаться к объектам типа Base и их наследникам. Цитата(Сергей Борщ @ Dec 3 2015, 12:44)  Указатель также уничтожается при выходе из функции, так что ругань идет на то, что объект уничтожается еще до присвоения указателю. И код полностью аналогичен вашему, насколько я понимаю. У меня указатель создается в конструкторе глобального объекта TInterface и уничтожаться он не должен.
--------------------
"Hello, word!" - 17 errors 56 warnings
|
|
|
|
|
Dec 3 2015, 08:59
|
Знающий
   
Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842

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

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Dec 3 2015, 09:52
|

Знающий
   
Группа: Свой
Сообщений: 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
|
|
|
|
|
Dec 3 2015, 10:24
|
Знающий
   
Группа: Свой
Сообщений: 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 (т.е. его можно написать слева от знака присваивания). В вашем случае это очевидно не так
|
|
|
|
|
Dec 7 2015, 06:37
|

Знающий
   
Группа: Свой
Сообщений: 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
|
|
|
|
|
Dec 7 2015, 06:54
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(WHALE @ Dec 7 2015, 09:37)  Base* pBase =&Derv1();
и Derv1 dv1; Base* pBase =&dv1;
Это ведь по сути одно и тоже и должно когмпилироваться в одинаковый ассемблерный код? Это не одно и тоже. В первом случае у вас временный объект, который будет уничтожен в конце выражения (на точке с запятой будет вызван его деструктор). После чего pBase указывает на некий мусор. Во втором случае dv1 живет до конца блока и деструктор будет вызван на } (или до конца программы, если это глобальная переменная) Если деструктора нет, то код может быть одинаковый. А может и нет, если компилятор решит соптимизировать и переиспользовать место на стеке
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|