Не компилируется программа 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?
Посмотрим внимательно на славное выражение 'ss=&(long)s;'.
Как нетрудно заметить, в нём:
*По-умному:*Берётся адрес результата преобразования указателя неведомого
нам (без привязки к конкретной архитектуре) размера к
типу long размером не менее 32 бит. Результат преобразования
не допускает присвоения в себя (не есть lvalue), следовательно,
от него нельзя брать адрес.
*На пальцах:*1. Выполняется преобразование значения указателя к типу
long, причём это значение не помещается ни в какую внятную
область памяти.
2. Производится взятие адреса от результата преобразования,
который, вообще-то говоря, нигде не хранится. От чего адрес-то
брать? О чём компилятор честно и сообщает.
>Посмотрим внимательно на славное выражение 'ss=&(long)s;'.
>Как нетрудно заметить, в нём:
>
>
>*По-умному:*
>
>Берётся адрес результата преобразования указателя неведомого
>нам (без привязки к конкретной архитектуре) размера к
>типу long размером не менее 32 бит. Результат преобразования
>не допускает присвоения в себя (не есть lvalue), следовательно,
>от него нельзя брать адрес.
>
>
>*На пальцах:*
>
> 1. Выполняется преобразование значения указателя к типу
>long, причём это значение не помещается ни в какую внятную
>область памяти.
> 2. Производится взятие адреса от результата преобразования,
>который, вообще-то говоря, нигде не хранится. От чего адрес-то
>брать? О чём компилятор честно и сообщает.хорошо. Спасибо, Dead Mustdie,но
код
(long)s=*ss
прекрасно компилируется
хотя слева стоит тот же пресловутый кастинг,
а насколько я знаю в стандарте iso9899 сказано, что слева в операторе
присваивания обязано быть lvalueИТАК ЯВЛЯЕТСЯ ЛИ РЕЗЛЬТАТ КАСТИНГА LVALUE.
PS
borland, M$, intel не выдают даже варнинга
>
>хорошо. Спасибо, Dead Mustdie,но кодВсегда пожалуйста :)
>(long)s=*ss
>прекрасно компилируется хотя слева стоит тот же пресловутый кастинг,
>а насколько я знаю в стандарте iso9899 сказано, что слева в операторе
>
>присваивания обязано быть lvalue
>
>ИТАК ЯВЛЯЕТСЯ ЛИ РЕЗЛЬТАТ КАСТИНГА LVALUE.
>Не является. О чём вполне внятно говорит тот же самый стандарт.
>PS
>borland, M$, intel не выдают даже варнингаПо правде говоря, это не фича, это - баг.
На системах где sizeof(long)!=sizeof(int) отсутствие на данной
строке "даже варнинга" будет очень дурно пахнуть.
т.е. код
(long)s=*ss
не должен компилиться
но gcc съдает ее
и еще
хотелось бы заиметь рускоязычный стандарт iso9899
спасибо
$
$ 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
$
>Не компилируется программа gcc 3.3.4 и более ранними
>ошибкаwhy not
void main(){
int s;
long *ss;
ss=&(long)s;
}don't cast adressof, cast variable instead
>>Не компилируется программа gcc 3.3.4 и более ранними
>>ошибка
>
>why not
>
>void main(){
>int s;
>long *ss;
> ss=&(long)s;
>}
>
>don't cast adressof, cast variable insteadSorry, was pasting wrong buffer :(
int
main() {
int s;
long *ss;ss = (long *)&s;
return 0;
}
Сие жульническтво может иметь нехорошие последствия
при sizeof(int)!=sizeof(long).
>Сие жульническтво может иметь нехорошие последствия
>при sizeof(int)!=sizeof(long).А как тогда передать в функцию по ссылке адрес указателя на запись, к которому применен кастинг (в си нет объектных штучек приходится извращаться)
такой код опасен?
t2 *vvv;
int fff(t1* v);sss=fff((t1 *)&vvv);
где t1 есть потомок t2 (если говорить в терминах ООП).
P.S.
Просто пишется конвертор с ООП-языка в си. как быть.
точнее прототип fff:
int fff(t1** v);
>А как тогда передать в функцию по ссылке адрес указателя на запись,
>к которому применен кастинг (в си нет объектных штучек приходится
>извращаться)
>
>такой код опасен?
>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;Во втором случае можно много чего словить :)