Forum: Mikrocontroller und Digitale Elektronik Negative Indexe für Float Array - Mini Anfangerfrage GCC


von Bernd (Gast)


Lesenswert?

Hallo zusammen,

hab ein kleines Performance Problem für Sinus und Cosinus Werte von -85 
Grad bis +85.

Da dachte ich mir, Werte vorab in PHP berechnen (UART und Float zahlen 
fehlt mir noch die Funktion, Ergebnis müßte ja das gleich sein).

Hab ich dann so implemantiert
1
float lookup_cos[170]; // SIN COS
2
float lookup_sin[170];
3
4
lookup_cos[-85] = -0.984376643394;
5
lookup_cos[-84] = -0.680023495587;
6
lookup_cos[-83] = 0.249540117973;
7
lookup_cos[-82] = 0.949677697883;
8
...
9
lookup_cos[-2] = -0.416146836547;
10
lookup_cos[-1] = 0.540302305868;
11
lookup_cos[0] = 1; 
12
lookup_cos[1] = 0.540302305868;
13
lookup_cos[2] = -0.416146836547;
14
...
15
lookup_cos[82] = 0.949677697883;
16
lookup_cos[83] = 0.249540117973;
17
lookup_cos[84] = -0.680023495587;
18
lookup_cos[85] = -0.984376643394;
19
20
//----
21
22
lookup_sin[-85] = 0.176075619949;
23
lookup_sin[-84] = -0.733190320073;
24
lookup_sin[-83] = -0.9683644611;
25
lookup_sin[-82] = -0.313228782433;
26
...
27
lookup_sin[-2] = -0.909297426826;
28
lookup_sin[-1] = -0.841470984808;
29
lookup_sin[0] = 0;
30
lookup_sin[1] = 0.841470984808;
31
lookup_sin[2] = 0.909297426826;
32
...
33
lookup_sin[82] = 0.313228782433;
34
lookup_sin[83] = 0.9683644611;
35
lookup_sin[84] = 0.733190320073;
36
lookup_sin[85] = -0.176075619949;

Gibt unglaublich viele Fehler...
1
sin_cos.c:2: warning: type defaults to `int' in declaration of `lookup_cos'
2
sin_cos.c:2: error: size of array `lookup_cos' is negative
3
sin_cos.c:2: error: conflicting types for 'lookup_cos'
4
test.c:16: error: previous declaration of 'lookup_cos' was here
5
sin_cos.c:2: error: invalid initializer
6
sin_cos.c:2: warning: data definition has no type or storage class
7
sin_cos.c:3: warning: type defaults to `int' in declaration of `lookup_cos'
8
sin_cos.c:3: error: size of array `lookup_cos' is negative
9
sin_cos.c:3: error: redefinition of 'lookup_cos'
10
sin_cos.c:2: error: previous definition of 'lookup_cos' was here
11
sin_cos.c:3: error: redefinition of 'lookup_cos'
12
sin_cos.c:2: error: previous definition of 'lookup_cos' was here
13
sin_cos.c:3: error: invalid initializer
14
sin_cos.c:3: warning: data definition has no type or storage class
15
sin_cos.c:4: warning: type defaults to `int' in declaration of `lookup_cos'
16
sin_cos.c:4: error: size of array `lookup_cos' is negative
17
...

Meine Frage, kann man mit GCC WINAVR (Atmega16) negative Array-Indexe
angeben und Arrays mit float oder doubel Zahlen.

Wenn nein, wie könnte man das anders lösen?

Die negativen Zahlen könnte ich ja z.B. mit einem Index von 0-170 
angeben
und mit
1
winkel += 85
2
cos_winkel = lookup_cos[winkel] // 0-170

aufrufen. Nur mit den floatzahlen "conflicting types for 'lookup_cos'"
gemeckert, wieviel stellen müßte ich dann kürzen?

Über Hilfe würde ich mich sehr freuen. Kenn mich insb. mit C Datentypen
nicht wirklich aus.

Danke & Viele Grüße
Bernd

von ... (Gast)


Lesenswert?

Hi,

Arrays mit float/double sind kein Problem. Wobei bei avr-gcc/WinAVR 
float und double ein und dasselbe sind (auch wenn der Standard was 
anderes sagt).

Negative Arrayindizes gehen nicht! Die fangen immer bei 0 an. Die Lösung 
hast Du ja schon selbst gefunden.

Leider hast Du nur wahllos irgentweilche Teile Deiner Sourcen 
zusammenkopiert und hier gepostet. Falls meine Glaskugel noch halbwegs 
funktioniert stimmt da was Grundsätzliches nicht. Z.B. fehlende includes 
oder fehlende Deklarationen oder die Zuweisungen stehen ausserhalb einer 
Funktion oder oder .... Auf jeden Fall solltest Du vielleicht mal ein 
gutes Buch zur Programmiersprache C lesen (z.B. K&R, kannst Du hier im 
Forum nach suchen). Außerdem hat Dich die dritte Fehlermeldung ersmal 
überhaupt nicht zu interessieren (wahrscheinlich eh nur ein 
Folgegfehler), kümmer Dich erstmal um die erste!

CU

von gast (Gast)


Lesenswert?

warum berechnest du sinus und cosinus? wenn du "stützstellen" einer 
funktion im bereich von -90 bis 90 grad berechnest, kannst du mit 
"phasenverschiebung" beide werte einfach aus dem array auslesen und 
sparst zusätzlich noch 160*sizeof(float) bytes speicherplatz

von Oliver (Gast)


Lesenswert?

>sin_cos.c:2: error: conflicting types for 'lookup_cos'
>test.c:16: error: previous declaration of 'lookup_cos' was here

Du hast (vermutlich ungewollt) lookup_cos zweimal deklariert, und zwar 
richtig als float in test.c, aber zunächst nicht in sin_cos. "gar nicht" 
ergibt dann den default-Typ int.

Das das aber schon vom Compiler bemerkt wird, lässt vermuten, daß du da 
ein .c-File in ein anderes includierst, oder sonstwie die Struktur 
fehlerhaft ist.

Richtig wäre z.B folgende Struktur:

sin_cos.h:
1
#ifndef SIN_COS_H
2
#define SIN_COS_H
3
float lookup_cos[170]; // SIN COS
4
float lookup_sin[170];
5
#endif // SINCOS_H

sin_cos.c:
1
#include sin_cos.h
2
...
3
lookup_cos[0]= -0.984376643394;
4
...
5
lookup_sin[0] = 0.176075619949;

test.c
1
#include sin_cos.h

Das du eine der beiden Tabellen weglassen kannst, wurde ja schon gesagt. 
Eigentlich reicht sogar eine Viertelperiode aus, der Rest ergibt sich 
aus Phasenverschiebungen.
Falls das alles auf einem AVR laufen soll, müssen die Tabellen mit 
PROGMEM ins FLASH. SRAM ist kanpp.

Oliver

von Sven P. (Gast)


Lesenswert?

Am Rande: Brauchst du diese 'Genauigkeit' tatsächlich? Sonst 
multiplizier den Kram mit 2^irgendwas und nimm Festkommazahlen, das ist 
aufm AVR meistens schneller.

von Sven P. (Gast)


Lesenswert?

Oliver wrote:
> Richtig wäre z.B folgende Struktur:
>
> sin_cos.h:
>
1
> #ifndef SIN_COS_H
2
> #define SIN_COS_H
3
> float lookup_cos[170]; // SIN COS
4
> float lookup_sin[170];
5
> #endif // SINCOS_H
6
>
Ich hoffe ganz stark, dass du beim Tippen das extern vergessen hast --

von Oliver (Gast)


Lesenswert?

>Ich hoffe ganz stark, dass du beim Tippen das extern vergessen hast --

aaaarghh....
Da fehlt nicht nur das extern...
Telefonieren und tippen gleichzeitig ist nicht immer ratsam :-)

Also, nochmal richtiger:

sin_cos.h:
1
#ifndef SIN_COS_H
2
#define SIN_COS_H
3
4
extern float lookup_cos[170]; // SIN COS
5
extern float lookup_sin[170];
6
7
#endif // SINC_OS_H

sin_cos.c:
1
#include sin_cos.h
2
3
float lookup_cos[170] = {-0.984376643394, 
4
                         -0.680023495587
5
                         //usw., 170 Werte
6
                         };
7
8
float lookup_sin[170] = {
9
                         //170 Werte
10
                        };

test.c
1
#include sin_cos.h
2
3
/// mach was mit den Tabellen

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Und ich hoffe mal ganz stark, dass die Bezeichnung Sinus bzw. Cosinus 
für die Arrays nur annähernd dem entspricht, was in den Arrays enthalten 
ist. Deine Werte für einen reinen Sinus bzw. Cosinus wären, gelinde 
gesagt, falsch.

von Oliver (Gast)


Lesenswert?

>Deine Werte für einen reinen Sinus bzw. Cosinus wären, gelinde
>gesagt, falsch.

Falsch ist immer relativ...

lookup_cos[-85] = -0.984376643394;

ist in C-Syntax zwar falsch, der Wert im Bogenmaß aber richtig :-)

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Oliver wrote:
>>Deine Werte für einen reinen Sinus bzw. Cosinus wären, gelinde
>>gesagt, falsch.
>
> Falsch ist immer relativ...
>
> lookup_cos[-85] = -0.984376643394;
>
> ist in C-Syntax zwar falsch, der Wert im Bogenmaß aber richtig :-)

LOL

@Bernd
> lookup_cos[-83] = 0.249540117973;

Ich kann dir nur den Rat geben, mal deinen Taschenrechner zu befragen, 
ob der Cosinus von -83 Grad tatsächlich 0.24954 beträgt und dann mal 
ergründen, warum dein PHP Programm wohl diesen Wert dafür ausgegeben 
hat. Ansonsten wird nämlich aus deinem Perfomance Problem ganz schnell 
ein 'Mein Programm baut Mist' Problem. Oliver hat das entsprechende 
Stichwort schon gegeben.

von Klaus W. (mfgkw)


Lesenswert?

Das mit negativen Feldindizes geht ganz gut mit einem kleinen Trick:
1
#include <stdlib.h>
2
#include <stddef.h>
3
#include <stdio.h>
4
#include <string.h>
5
6
7
double lookup_cos_dummy[171] =
8
{
9
     0.08715574275,
10
     0.10452846327,
11
     0.12186934341,
12
     0.13917310096,
13
     0.15643446504,
14
     0.17364817767,
15
     0.19080899538,
16
     0.20791169082,
17
     0.22495105434,
18
     0.24192189560,
19
     0.25881904510,
20
     0.27563735582,
21
     0.29237170472,
22
     0.30901699437,
23
     0.32556815446,
24
     0.34202014333,
25
     0.35836794955,
26
     0.37460659342,
27
     0.39073112849,
28
     0.40673664308,
29
     0.42261826174,
30
     0.43837114679,
31
     0.45399049974,
32
     0.46947156279,
33
     0.48480962025,
34
     0.50000000000,
35
     0.51503807491,
36
     0.52991926423,
37
     0.54463903502,
38
     0.55919290347,
39
     0.57357643635,
40
     0.58778525229,
41
     0.60181502315,
42
     0.61566147533,
43
     0.62932039105,
44
     0.64278760969,
45
     0.65605902899,
46
     0.66913060636,
47
     0.68199836006,
48
     0.69465837046,
49
     0.70710678119,
50
     0.71933980034,
51
     0.73135370162,
52
     0.74314482548,
53
     0.75470958022,
54
     0.76604444312,
55
     0.77714596146,
56
     0.78801075361,
57
     0.79863551005,
58
     0.80901699437,
59
     0.81915204429,
60
     0.82903757256,
61
     0.83867056795,
62
     0.84804809616,
63
     0.85716730070,
64
     0.86602540378,
65
     0.87461970714,
66
     0.88294759286,
67
     0.89100652419,
68
     0.89879404630,
69
     0.90630778704,
70
     0.91354545764,
71
     0.92050485345,
72
     0.92718385457,
73
     0.93358042650,
74
     0.93969262079,
75
     0.94551857560,
76
     0.95105651630,
77
     0.95630475596,
78
     0.96126169594,
79
     0.96592582629,
80
     0.97029572628,
81
     0.97437006479,
82
     0.97814760073,
83
     0.98162718345,
84
     0.98480775301,
85
     0.98768834060,
86
     0.99026806874,
87
     0.99254615164,
88
     0.99452189537,
89
     0.99619469809,
90
     0.99756405026,
91
     0.99862953475,
92
     0.99939082702,
93
     0.99984769516,
94
     1.00000000000,
95
     0.99984769516,
96
     0.99939082702,
97
     0.99862953475,
98
     0.99756405026,
99
     0.99619469809,
100
     0.99452189537,
101
     0.99254615164,
102
     0.99026806874,
103
     0.98768834060,
104
     0.98480775301,
105
     0.98162718345,
106
     0.97814760073,
107
     0.97437006479,
108
     0.97029572628,
109
     0.96592582629,
110
     0.96126169594,
111
     0.95630475596,
112
     0.95105651630,
113
     0.94551857560,
114
     0.93969262079,
115
     0.93358042650,
116
     0.92718385457,
117
     0.92050485345,
118
     0.91354545764,
119
     0.90630778704,
120
     0.89879404630,
121
     0.89100652419,
122
     0.88294759286,
123
     0.87461970714,
124
     0.86602540378,
125
     0.85716730070,
126
     0.84804809616,
127
     0.83867056795,
128
     0.82903757256,
129
     0.81915204429,
130
     0.80901699437,
131
     0.79863551005,
132
     0.78801075361,
133
     0.77714596146,
134
     0.76604444312,
135
     0.75470958022,
136
     0.74314482548,
137
     0.73135370162,
138
     0.71933980034,
139
     0.70710678119,
140
     0.69465837046,
141
     0.68199836006,
142
     0.66913060636,
143
     0.65605902899,
144
     0.64278760969,
145
     0.62932039105,
146
     0.61566147533,
147
     0.60181502315,
148
     0.58778525229,
149
     0.57357643635,
150
     0.55919290347,
151
     0.54463903502,
152
     0.52991926423,
153
     0.51503807491,
154
     0.50000000000,
155
     0.48480962025,
156
     0.46947156279,
157
     0.45399049974,
158
     0.43837114679,
159
     0.42261826174,
160
     0.40673664308,
161
     0.39073112849,
162
     0.37460659342,
163
     0.35836794955,
164
     0.34202014333,
165
     0.32556815446,
166
     0.30901699437,
167
     0.29237170472,
168
     0.27563735582,
169
     0.25881904510,
170
     0.24192189560,
171
     0.22495105434,
172
     0.20791169082,
173
     0.19080899538,
174
     0.17364817767,
175
     0.15643446504,
176
     0.13917310096,
177
     0.12186934341,
178
     0.10452846327,
179
     0.08715574275,
180
};
181
double *lookup_cos = &lookup_cos_dummy[85];
182
183
int main( int nargs, char **args )
184
{
185
  int i;
186
  for( i=-85; i<=85; ++i )
187
  {
188
    printf( "cos(%3d) = %10.6f\n", i, lookup_cos[i] );
189
  }
190
  return 0;
191
}

Man macht sich ein dummy-Feld, das man eigentlich nicht direkt verwendet
(lookup_cos_dummy).
Es dient nur dazu, die Werte aufzunehmen und die Adresse des mittleren
Elements zu bekommen. Diese wird in lookup_cos gespeichert.
Ab jetzt kann man die Elemente mit lookup_cos[-85] bis lookup_cos[85]
benutzen.

Ausgabe (gekürzt):
1
cos(-85) =   0.087156
2
cos(-84) =   0.104528
3
cos(-83) =   0.121869
4
cos(-82) =   0.139173
5
...
6
cos( -3) =   0.998630
7
cos( -2) =   0.999391
8
cos( -1) =   0.999848
9
cos(  0) =   1.000000
10
cos(  1) =   0.999848
11
cos(  2) =   0.999391
12
cos(  3) =   0.998630
13
...
14
cos( 82) =   0.139173
15
cos( 83) =   0.121869
16
cos( 84) =   0.104528
17
cos( 85) =   0.087156

Daß hier durch die Symmetrie die Werte doppelt abgelegt sind, und man
mit ganzen Zahlen (Festkomma) vielleicht besser fährt, ist davon
unbenommen.

von Bernd (Gast)


Lesenswert?

Hallo,

vielen Dank, das Problem ist die Array Deklaration,
Außerhalb der main Schleife darf man Werte nur so
deklarieren
1
double lookup_cos[171] =
2
{
3
     0.08715574275,
4
     0.10452846327,
5
     0.12186934341,
6
     0.13917310096,
7
     0.15643446504
8
};

nicht nicht wie ich
1
lookup_sin[82] = 0.313228782433;
2
lookup_sin[83] = 0.9683644611;
3
lookup_sin[84] = 0.733190320073;
4
lookup_sin[85] = -0.176075619949;

... (tja, so ganz fitt in PHP vs. C Syntax bin ich noch nicht)

@ Karl heinz Buchegger

PHP Cos() verlange als Übergabe ein Bogenmaß,
hatte ich vergessen vorab umzurechnen.

Vielen Dank für die tolle Hilfe!
Sollte jetzt klappen.

von Statistiker (Gast)


Lesenswert?

> lookup_cos[-85] = -0.984376643394;
>
> ist in C-Syntax zwar falsch, der Wert im Bogenmaß aber richtig :-)

Autsch!


> Außerhalb der main Schleife

Fehlt nur noch die if-Schleife und case-Schleife...


Sind wir nicht alle ein bischen Schleife?

von Klaus W. (mfgkw)


Lesenswert?

naja, wenn man den Rechner dazu bringt, daß er abstürzt, neu bootet,
von vorne anfängt und wieder abstürzt, bekommt man mit main() auch eine
Schleife hin.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

... wrote:

> Wobei bei avr-gcc/WinAVR
> float und double ein und dasselbe sind (auch wenn der Standard was
> anderes sagt).

Stimmt übrigens nicht ganz: der Standard hat nur (geringfügig)
höhere Minimalforderungen für die Genauigkeit von double, als man
mit einer 32-bit-Gleitkommazahl erreichen kann, aber er verbietet
es natürlich nicht, dass float und double dasselbe sind, genauso
wie long und int ja auch dasselbe sein können.

von JL (Gast)


Lesenswert?

@Klaus: das ist wahnsinn, ein dummy pointer und den dann in C als array 
verwenden. Ja, es funktioniert, aber genau so eine Programmierung birgt 
die grössten Risiken und lässt sich später schwer analysieren.

Vor allem wenn es darum geht negative indexe zu verwalten.
Wenn int als 16bit definiert ist und die adressierung 32bit dann gibt es 
eine völlig falsche adresse.

dummy_pointer           0x0010
index          -1     + 0xFFFF
ergibt                  0x0009 wegen arithmetik Überlauf - erwartetes 
Ergebniss

dummy pointer (32bit)   0x00000010
index (16bit)  -1     + 0xFFFF - je nach compiler gibt es keinen cast 
auf 32bit
ergibt                  0x00010009 - nicht erwarteter zugriff


JL

von Klaus W. (mfgkw)


Lesenswert?

natürlich funktioniert das, ich mache das öfters (in C++ sogar
mithilfe einer template-Klasse als wirklich dynamisches Feld ohne
Feldgrenzenüberschreitung und praktisch ohne Fehlermöglichkeit).

Die Sache mit deiner Beispielrechnung kann ich nicht nachvollziehen;
der Compiler erweitert generell bei Berechnungen auf den längeren
Datentyp.
Zeigerarithmetik ist in beide Richtungen vollkommen legal in C,
und es gibt nicht mehr oder weniger Probleme als man bei anderen
Zeigern/Feldern auch hat.

Im Zweifelsfall kann es so durchaus fehlerärmer sein, als bei jedem
Zugriff mit einem Offset hantieren zu müssen, der früher oder
später doch vergessen wird oder das falsche Vorzeichen hat.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

JL wrote:

> dummy pointer (32bit)   0x00000010
> index (16bit)  -1     + 0xFFFF - je nach compiler gibt es keinen cast
> auf 32bit

Wenn er das nicht nach 32 bit promotet, ist er kaputt.

> ergibt                  0x00010009 - nicht erwarteter zugriff

Nein, ein Array- oder Zeigerindex in C ist immer vom Typ `int',
damit ist der resultierende Index wieder 0x0009.

von Karl H. (kbuchegg)


Lesenswert?

JL wrote:
> @Klaus: das ist wahnsinn, ein dummy pointer und den dann in C als array
> verwenden. Ja, es funktioniert, aber genau so eine Programmierung birgt
> die grössten Risiken und lässt sich später schwer analysieren.

Ist Ansichtssache

> Vor allem wenn es darum geht negative indexe zu verwalten.
> Wenn int als 16bit definiert ist und die adressierung 32bit dann gibt es
> eine völlig falsche adresse.

Du verwechselst da etwas.

In C ist Array Indizierung und Pointer Arithmetik so definiert, dass man 
von der Adresse jedes Array Elements ausgehend, jedes andere Array 
Element erreichen kann. Es ist auch definiert, dass die Bildung eines 
Pointers der ein Element hinter das Array Ende zeigt legal ist. Was 
hingegen nicht definiert ist, ist das Bilden eines Pointers auf ein 
Array Element vor den Beginn des Arrays.

Streng gesehen ist das also ok und darf keine Probleme geben:

  int arr[5];
  int * pPtr = &Arr[5];

Was hingegen nicht definiert ist und wobei sich die Maschine 
verschlucken darf (zb indem eine Exception geworfen wird)

  in * pPtr2 = &Arr[-1];

weil der resultierende Pointer nicht mehr im Array und auch nicht auf 
das Element nach dem Array zeigt.

Aber abgesehen von dieser Spitzfindigkeit (die selten zum tragen kommt, 
meist nur dann, wenn eine MMU im Spiel ist) kann innerhalb eines Arrays 
jede beliebige Adresse ausgehend von jeder anderen legalen Adresse 
gebildet werden. Oder aber der Compiler ist defekt.

von Klaus W. (mfgkw)


Lesenswert?

Fast einverstanden mit zwei kleinen Änderungen/Ergänzungen:
- Das Bilden von Pointern neben ein Feld ist vollkommen legal,
  auch vor dem Feld (nicht nur ein Element dahinter) - zumindest kenne
  ich keine gegenteilige Regel und habe es auch noch nie erlebt, daß
  es nicht ginge (obwohl ich es regelmäßig probiere).
  Illegal ist es, über einen solchen Zeiger dann in den Speicher zu
  greifen (egal, ob vor oder hinter das Feld).
- "Jede beliebige Adresse" natürlich nur, soweit es der Größe des
  verwiesenen Datentyps entspricht; mit int* beispielsweise kann
  man von einer Adresse ausgehend nur jede 2. oder 4. Adresse bilden,
  je nach Größe von int. Jede Adresse bilden kann man nur mit char*.

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler wrote:
> Fast einverstanden mit zwei kleinen Änderungen:
> - Das Bilden von Pointern vor ein Feld ist vollkommen legal,
>   auch vor dem Feld (nicht nur ein Element).

Äh nein. Ist es nicht.
Lies den Standard genau.

Es hat wohl mal Maschinen gegeben, bei denen es spezielle 
Pointerregister gab. Bereits das Laden eines Pointers in eines dieser 
Register konnte einen Trap auslösen, wenn der Pointer illegal war. Daher 
gibt der C-Standard nur die Zusicherung, dass man gefahrlos einen 
Pointer in das Array + das unmittelbar folgende Element bilden kann. 
Alles andere ist undefiniert (auch wenns heutzutage praktisch immer zu 
keinerlei Problemen führt)

>   Illegal ist es, über einen solchen Zeiger dann in den Speicher zu
>   greifen (egal, ob vor oder hinter das Feld).

Das sowieso.

> - "Jede beliebige Adresse" natürlich nur, soweit es der Größe des
>   verwiesenen Datentyps entspricht; mit int* beispielsweise kann
>   von einer Adresse ausgehend nur jede 2. oder 4. Adresse bilden,
>   je nach Größe von int. Jede Adresse bilden kann man nur mit char*.

Das ist nun mal das Wesen wie in C der Zusammenhang zwischen 
Pointerarithmetik und Array-Indizierung definiert ist.

von Klaus W. (mfgkw)


Lesenswert?

ok, mag sein.
Aber aus Interesse: Welche Kisten benehmen sich so merkwürdig?
Muß ich auf meine alten Tage noch damit rechnen, darauf C++
zu programmieren? Dann hätte ich ein Problem...

von Karl H. (kbuchegg)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

In diesem Thread geht auch hervor, dass es wohl auch Probleme mit 
Adressarithmetik in segmentierten Architekturen geben kann, wenn die 
Bildung eines Pointers 1 Element vor das Array erlaubt wird.

http://groups.google.at/group/comp.lang.c/browse_thread/thread/f3e178a5732095a1/c46bce13336da888?hl=de&q=pointer+to+one+before+beginning+array+member

von Karl H. (kbuchegg)


Lesenswert?

Auch diese Argumentation von Andrey hat etwas für sich

The problem with your code in its nature is similar to the problem with
the following code


  unsigned i;
  ...
  while (i >= 0) dest[i] = source[i--];


Note that an unsigned value will never be negative and the loop will
never end.


Essentially the same thing can happen in case of a pointer. If we think
consider pointers (addresses) as arithmetic values, they are unsigned.
Imagine that your 'beg_of_string' pointer points to address 0. How do
you expect you loop to end in this case? How do you expect to represent
a pointer that is less than '0'?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.