URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 4143
[ Назад ]

Исходное сообщение
"Поддержка ansi c99 в GCC"

Отправлено asipin , 05-Апр-05 09:43 
Не компилируется программа gcc 3.3.4 и более ранними
ошибка
root@unconnected:~/delme/p21# gcc ppp.c
ppp.c: In function `main':
ppp.c:4: error: invalid lvalue in unary `&'
ppp.c:1: warning: return type of `main' is not `int'

root@unconnected:~/delme/p21# cat ppp.c
void main(){
int s;
long *ss;
  ss=&(long)s;
}


root@unconnected:~/delme/p21# gcc -std=c99 ppp.c
ppp.c: In function `main':
ppp.c:4: error: invalid lvalue in unary `&'
ppp.c:1: warning: return type of `main' is not `int'

почему casting не является lvalue?


Содержание

Сообщения в этом обсуждении
"Поддержка ansi c99 в GCC"
Отправлено Dead Mustdie , 05-Апр-05 10:38 
Посмотрим внимательно на славное выражение 'ss=&(long)s;'.
Как нетрудно заметить, в нём:


*По-умному:*

Берётся адрес результата преобразования указателя неведомого
нам (без привязки к конкретной архитектуре) размера к
типу long размером не менее 32 бит. Результат преобразования
не допускает присвоения в себя (не есть lvalue), следовательно,
от него нельзя брать адрес.


*На пальцах:*

  1. Выполняется преобразование значения указателя к типу
long, причём это значение не помещается ни в какую внятную
область памяти.
  2. Производится взятие адреса от результата преобразования,
который, вообще-то говоря, нигде не хранится. От чего адрес-то
брать? О чём компилятор честно и сообщает.


"Поддержка ansi c99 в GCC"
Отправлено pm_kAs , 05-Апр-05 14:39 
>Посмотрим внимательно на славное выражение 'ss=&(long)s;'.
>Как нетрудно заметить, в нём:
>
>
>*По-умному:*
>
>Берётся адрес результата преобразования указателя неведомого
>нам (без привязки к конкретной архитектуре) размера к
>типу long размером не менее 32 бит. Результат преобразования
>не допускает присвоения в себя (не есть lvalue), следовательно,
>от него нельзя брать адрес.
>
>
>*На пальцах:*
>
>  1. Выполняется преобразование значения указателя к типу
>long, причём это значение не помещается ни в какую внятную
>область памяти.
>  2. Производится взятие адреса от результата преобразования,
>который, вообще-то говоря, нигде не хранится. От чего адрес-то
>брать? О чём компилятор честно и сообщает.

хорошо. Спасибо, Dead Mustdie,но
код
(long)s=*ss
прекрасно компилируется
хотя слева  стоит тот же пресловутый кастинг,
а насколько я знаю в стандарте iso9899 сказано, что слева в операторе
присваивания обязано быть lvalue

ИТАК ЯВЛЯЕТСЯ ЛИ РЕЗЛЬТАТ КАСТИНГА LVALUE.

PS
borland, M$, intel не выдают даже варнинга


"Поддержка ansi c99 в GCC"
Отправлено Dead Mustdie , 05-Апр-05 14:46 
>
>хорошо. Спасибо, Dead Mustdie,но код

Всегда пожалуйста :)

>(long)s=*ss
>прекрасно компилируется хотя слева  стоит тот же пресловутый кастинг,
>а насколько я знаю в стандарте iso9899 сказано, что слева в операторе
>
>присваивания обязано быть lvalue
>
>ИТАК ЯВЛЯЕТСЯ ЛИ РЕЗЛЬТАТ КАСТИНГА LVALUE.
>

Не является. О чём вполне внятно говорит тот же самый стандарт.

>PS
>borland, M$, intel не выдают даже варнинга

По правде говоря, это не фича, это - баг.
На системах где sizeof(long)!=sizeof(int) отсутствие на данной
строке "даже варнинга" будет очень дурно пахнуть.


"Поддержка ansi c99 в GCC"
Отправлено pm_kAs , 05-Апр-05 15:06 
т.е. код
(long)s=*ss
не должен компилиться
но gcc съдает ее
и еще
хотелось бы заиметь рускоязычный стандарт iso9899
спасибо

"Поддержка ansi c99 в GCC"
Отправлено Dead Mustdie , 05-Апр-05 15:16 
$
$ echo "int main() {
          int s; long val=0;
          long* ss=&val;
          (long)s = *ss; return 0;
}" >test.c
$ gcc test.c -o test
test.c: In function `main':
test.c:4: warning: use of cast expressions as lvalues is deprecated
$ gcc -v
Reading specs from /opt/dev-tools/lib/gcc/i686-pc-linux-gnu/3.4.3/specs
Configured with: /home/zinal/Build/gcc-3.4.3/configure --prefix=/opt/dev-tools --enable-threads=posix --enable-languages=c,c++,f77 --disable-nls
Thread model: posix
gcc version 3.4.3
$

"Поддержка ansi c99 в GCC"
Отправлено Dill , 10-Апр-05 17:44 
>Не компилируется программа gcc 3.3.4 и более ранними
>ошибка

why not

void main(){
int s;
long *ss;
  ss=&(long)s;
}

don't cast adressof, cast variable instead


"Поддержка ansi c99 в GCC"
Отправлено Dill , 10-Апр-05 17:46 
>>Не компилируется программа gcc 3.3.4 и более ранними
>>ошибка
>
>why not
>
>void main(){
>int s;
>long *ss;
>  ss=&(long)s;
>}
>
>don't cast adressof, cast variable instead

Sorry, was pasting wrong buffer :(

int
main() {
        int s;
        long *ss;

        ss = (long *)&s;

        return 0;
}



"Поддержка ansi c99 в GCC"
Отправлено DeadMustdie , 11-Апр-05 13:22 
Сие жульническтво может иметь нехорошие последствия
при sizeof(int)!=sizeof(long).

"Поддержка ansi c99 в GCC"
Отправлено pm_kas , 11-Апр-05 17:14 
>Сие жульническтво может иметь нехорошие последствия
>при sizeof(int)!=sizeof(long).

А как тогда передать в функцию по ссылке адрес указателя на запись, к которому применен кастинг (в си нет объектных штучек приходится извращаться)
такой код опасен?
t2 *vvv;
int fff(t1* v);

sss=fff((t1 *)&vvv);

где t1 есть потомок t2 (если говорить в терминах ООП).

P.S.
  Просто пишется конвертор с ООП-языка в си. как быть.


"Поддержка ansi c99 в GCC"
Отправлено pm_kas , 11-Апр-05 17:22 
точнее прототип fff:
int fff(t1** v);

"Поддержка ansi c99 в GCC"
Отправлено DeadMustdie , 11-Апр-05 18:59 
>А как тогда передать в функцию по ссылке адрес указателя на запись,
>к которому применен кастинг (в си нет объектных штучек приходится
>извращаться)
>
>такой код опасен?
>t2 *vvv;
>int fff(t1** v);
>
>sss=fff((t1 *)&vvv);
>
>где t1 есть потомок t2 (если говорить в терминах ООП).
>

Это другой случай. Если sizeof(t2)>=sizeof(t1), и данные,
размещённые "в начале" t2 совпадают по структуре с данными
в t1, то всё вполне безопасно. Feel the difference:

  long val;
  int *pval = (int*)&val;
  *pval = 10;

vs

  int val;
  long *pval = (long*)&val;
  *pval = 10;

Во втором случае можно много чего словить :)