Discussion:
error: lvalue required as left operand of assignment
(zu alt für eine Antwort)
Martin Klaiber
2014-09-22 07:54:54 UTC
Permalink
Raw Message
Hallo,

ich hoffe, ich bin hier mit meiner Frage richtig. Ich wollte ein
Programmpaket, das ich vor vielen Jahren schon einmal benutzt hatte,
erneut kompilieren und erhalte nun die im Subject genannte
Fehlermeldung.

Es handelt sich um das nwfiir-Paket von Anders Torger:

<http://www.ludd.luth.se/~torger/filter.html>

Source-Code (58 kB):

<http://www.ludd.luth.se/~torger/files/wfir.tar.gz>

Das Paket wird schon lange nicht mehr weiterentwickelt, der Autor
bietet aber an, ihn bei Problemen zu kontaktieren. Bevor ich das
tue, wollte ich aber kurz hier nachfragen, ob es sich tatsächlich um
ein Problem mit dem Code handelt oder der Fehler bei mir liegt, denn
meine C-Kenntnisse sind nicht allzu gut.

Rufe ich "make" auf, erhalte ich folgende Meldungen:

gcc -c -I/usr/local/include -Wall -Winline -malign-double -O2 -DARCH_IA32 -DALSA mls2imp.c
In file included from mls2imp.c:15:0:
sample.h: In function 'sample_raw2int':
sample.h:54:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
sample.h: In function 'sample_int2raw':
sample.h:105:19: error: lvalue required as left operand of assignment
sample.h:116:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
make: *** [mls2imp.o] Error 1

Der Code rund um Zeile 105 in sample.h lautet:

99 static inline void
100 sample_int2raw(struct sample_format *sf,
101 void *p,
102 int32_t sample)
103 {
104 if (!sf->is_signed) {
105 (uint32_t)sample -= (1 << (sf->bits - 1));
106 }
107 sample <<= sf->left_shift;
108 if (sf->swap) {
109 sample = (sf->bytes == 2) ? SWAP16(sample) : SWAP32(sample);
110 }

Der problematische Teil des Codes scheint also das "-=" zu sein. Ich
habe im web schon mal ein bisschen nach der Fehlermeldung gesucht,
aber hauptsächlich Meldungen für das Problem gefunden, dass jemand
"=" und "==" verwechselt hatte.

Mich verwundert vorallem, dass der Code früher problemlos compilierte.
War der Code schon immer problematisch und ist nur der Compiler
inzwischen strenger? Oder mache ich was falsch, fehlen mir Libraries/
Programme/etc?

Kompiliert habe ich auf einem Debian-wheezy-System. gcc -v:

gcc version 4.7.2 (Debian 4.7.2-5)

Hardware ist ein Thinkpad X40, also nichts exotisches (Intel Pentium-M).
uname -a:

Linux maurice 3.2.0-4-486 #1 Debian 3.2.60-1+deb7u3 i686 GNU/Linux

Das Kompilieren klappte damals auf einem Debian 2.2r2, gcc könnte gemäß
<https://wiki.debian.org/DebianPotato> 2.95.2 gewesen sein.

Danke und Grüße
Martin
Rainer Weikusat
2014-09-22 10:40:33 UTC
Permalink
Raw Message
Martin Klaiber <***@gmx.de> writes:

[...]
Post by Martin Klaiber
gcc -c -I/usr/local/include -Wall -Winline -malign-double -O2 -DARCH_IA32 -DALSA mls2imp.c
sample.h:54:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
sample.h:105:19: error: lvalue required as left operand of assignment
sample.h:116:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
make: *** [mls2imp.o] Error 1
99 static inline void
100 sample_int2raw(struct sample_format *sf,
101 void *p,
102 int32_t sample)
103 {
104 if (!sf->is_signed) {
105 (uint32_t)sample -= (1 << (sf->bits - 1));
106 }
107 sample <<= sf->left_shift;
108 if (sf->swap) {
109 sample = (sf->bytes == 2) ? SWAP16(sample) : SWAP32(sample);
110 }
Der problematische Teil des Codes scheint also das "-=" zu sein.
Der 'problematische Teil' ist der (uint32_t) cast. Dessen Resultat ist
kein lvalue, also kann ihm auch nichts zugewiesen werden. Die
interessantere Frage ist allerdings 'Was soll das?'. Es koennte dafuer
gedacht sein, ein Vorzeichenbit zu loeschen, wofuer auch immer das gut
sein soll (wenn sf->bits die Breite eines Typs waere, waere

1 << (sf->bit - 1)

ein Zahl, bei der ausschliesslich das hoechste Bit gesetzt ist). Man
kann das in jedem Fall durch

sample = (uint32_t)sample - (1 << (sf->bits - 1))

ersetzen. Ich bezweifle allerdings, dass der cast ueberhaupt einen Sinn
hat (koennte mich aber durchaus irren).
Florian Weimer
2014-09-22 16:53:16 UTC
Permalink
Raw Message
Post by Martin Klaiber
104 if (!sf->is_signed) {
105 (uint32_t)sample -= (1 << (sf->bits - 1));
106 }
Gemeint war vermutlich:

sample = ((uint32_t) sample) - (1U << (sf->bits - 1));
Post by Martin Klaiber
Mich verwundert vorallem, dass der Code früher problemlos compilierte.
War der Code schon immer problematisch und ist nur der Compiler
inzwischen strenger?
Der Compiler hatte einen Bug.

Loading...