mikrocontroller.net

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


Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
float lookup_cos[170]; // SIN COS
float lookup_sin[170];

lookup_cos[-85] = -0.984376643394;
lookup_cos[-84] = -0.680023495587;
lookup_cos[-83] = 0.249540117973;
lookup_cos[-82] = 0.949677697883;
...
lookup_cos[-2] = -0.416146836547;
lookup_cos[-1] = 0.540302305868;
lookup_cos[0] = 1; 
lookup_cos[1] = 0.540302305868;
lookup_cos[2] = -0.416146836547;
...
lookup_cos[82] = 0.949677697883;
lookup_cos[83] = 0.249540117973;
lookup_cos[84] = -0.680023495587;
lookup_cos[85] = -0.984376643394;

//----

lookup_sin[-85] = 0.176075619949;
lookup_sin[-84] = -0.733190320073;
lookup_sin[-83] = -0.9683644611;
lookup_sin[-82] = -0.313228782433;
...
lookup_sin[-2] = -0.909297426826;
lookup_sin[-1] = -0.841470984808;
lookup_sin[0] = 0;
lookup_sin[1] = 0.841470984808;
lookup_sin[2] = 0.909297426826;
...
lookup_sin[82] = 0.313228782433;
lookup_sin[83] = 0.9683644611;
lookup_sin[84] = 0.733190320073;
lookup_sin[85] = -0.176075619949;

Gibt unglaublich viele Fehler...
sin_cos.c:2: warning: type defaults to `int' in declaration of `lookup_cos'
sin_cos.c:2: error: size of array `lookup_cos' is negative
sin_cos.c:2: error: conflicting types for 'lookup_cos'
test.c:16: error: previous declaration of 'lookup_cos' was here
sin_cos.c:2: error: invalid initializer
sin_cos.c:2: warning: data definition has no type or storage class
sin_cos.c:3: warning: type defaults to `int' in declaration of `lookup_cos'
sin_cos.c:3: error: size of array `lookup_cos' is negative
sin_cos.c:3: error: redefinition of 'lookup_cos'
sin_cos.c:2: error: previous definition of 'lookup_cos' was here
sin_cos.c:3: error: redefinition of 'lookup_cos'
sin_cos.c:2: error: previous definition of 'lookup_cos' was here
sin_cos.c:3: error: invalid initializer
sin_cos.c:3: warning: data definition has no type or storage class
sin_cos.c:4: warning: type defaults to `int' in declaration of `lookup_cos'
sin_cos.c:4: error: size of array `lookup_cos' is negative
...

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
winkel += 85
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

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#ifndef SIN_COS_H
#define SIN_COS_H
float lookup_cos[170]; // SIN COS
float lookup_sin[170];
#endif // SINCOS_H

sin_cos.c:
#include sin_cos.h
...
lookup_cos[0]= -0.984376643394;
...
lookup_sin[0] = 0.176075619949;

test.c
#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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sven P. (haku) Benutzerseite
Datum:

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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#ifndef SIN_COS_H
#define SIN_COS_H

extern float lookup_cos[170]; // SIN COS
extern float lookup_sin[170];

#endif // SINC_OS_H

sin_cos.c:
#include sin_cos.h

float lookup_cos[170] = {-0.984376643394, 
                         -0.680023495587
                         //usw., 170 Werte
                         };

float lookup_sin[170] = {
                         //170 Werte
                        };

test.c
#include sin_cos.h

/// mach was mit den Tabellen

Oliver

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit negativen Feldindizes geht ganz gut mit einem kleinen Trick:
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>


double lookup_cos_dummy[171] =
{
     0.08715574275,
     0.10452846327,
     0.12186934341,
     0.13917310096,
     0.15643446504,
     0.17364817767,
     0.19080899538,
     0.20791169082,
     0.22495105434,
     0.24192189560,
     0.25881904510,
     0.27563735582,
     0.29237170472,
     0.30901699437,
     0.32556815446,
     0.34202014333,
     0.35836794955,
     0.37460659342,
     0.39073112849,
     0.40673664308,
     0.42261826174,
     0.43837114679,
     0.45399049974,
     0.46947156279,
     0.48480962025,
     0.50000000000,
     0.51503807491,
     0.52991926423,
     0.54463903502,
     0.55919290347,
     0.57357643635,
     0.58778525229,
     0.60181502315,
     0.61566147533,
     0.62932039105,
     0.64278760969,
     0.65605902899,
     0.66913060636,
     0.68199836006,
     0.69465837046,
     0.70710678119,
     0.71933980034,
     0.73135370162,
     0.74314482548,
     0.75470958022,
     0.76604444312,
     0.77714596146,
     0.78801075361,
     0.79863551005,
     0.80901699437,
     0.81915204429,
     0.82903757256,
     0.83867056795,
     0.84804809616,
     0.85716730070,
     0.86602540378,
     0.87461970714,
     0.88294759286,
     0.89100652419,
     0.89879404630,
     0.90630778704,
     0.91354545764,
     0.92050485345,
     0.92718385457,
     0.93358042650,
     0.93969262079,
     0.94551857560,
     0.95105651630,
     0.95630475596,
     0.96126169594,
     0.96592582629,
     0.97029572628,
     0.97437006479,
     0.97814760073,
     0.98162718345,
     0.98480775301,
     0.98768834060,
     0.99026806874,
     0.99254615164,
     0.99452189537,
     0.99619469809,
     0.99756405026,
     0.99862953475,
     0.99939082702,
     0.99984769516,
     1.00000000000,
     0.99984769516,
     0.99939082702,
     0.99862953475,
     0.99756405026,
     0.99619469809,
     0.99452189537,
     0.99254615164,
     0.99026806874,
     0.98768834060,
     0.98480775301,
     0.98162718345,
     0.97814760073,
     0.97437006479,
     0.97029572628,
     0.96592582629,
     0.96126169594,
     0.95630475596,
     0.95105651630,
     0.94551857560,
     0.93969262079,
     0.93358042650,
     0.92718385457,
     0.92050485345,
     0.91354545764,
     0.90630778704,
     0.89879404630,
     0.89100652419,
     0.88294759286,
     0.87461970714,
     0.86602540378,
     0.85716730070,
     0.84804809616,
     0.83867056795,
     0.82903757256,
     0.81915204429,
     0.80901699437,
     0.79863551005,
     0.78801075361,
     0.77714596146,
     0.76604444312,
     0.75470958022,
     0.74314482548,
     0.73135370162,
     0.71933980034,
     0.70710678119,
     0.69465837046,
     0.68199836006,
     0.66913060636,
     0.65605902899,
     0.64278760969,
     0.62932039105,
     0.61566147533,
     0.60181502315,
     0.58778525229,
     0.57357643635,
     0.55919290347,
     0.54463903502,
     0.52991926423,
     0.51503807491,
     0.50000000000,
     0.48480962025,
     0.46947156279,
     0.45399049974,
     0.43837114679,
     0.42261826174,
     0.40673664308,
     0.39073112849,
     0.37460659342,
     0.35836794955,
     0.34202014333,
     0.32556815446,
     0.30901699437,
     0.29237170472,
     0.27563735582,
     0.25881904510,
     0.24192189560,
     0.22495105434,
     0.20791169082,
     0.19080899538,
     0.17364817767,
     0.15643446504,
     0.13917310096,
     0.12186934341,
     0.10452846327,
     0.08715574275,
};
double *lookup_cos = &lookup_cos_dummy[85];

int main( int nargs, char **args )
{
  int i;
  for( i=-85; i<=85; ++i )
  {
    printf( "cos(%3d) = %10.6f\n", i, lookup_cos[i] );
  }
  return 0;
}

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):
cos(-85) =   0.087156
cos(-84) =   0.104528
cos(-83) =   0.121869
cos(-82) =   0.139173
...
cos( -3) =   0.998630
cos( -2) =   0.999391
cos( -1) =   0.999848
cos(  0) =   1.000000
cos(  1) =   0.999848
cos(  2) =   0.999391
cos(  3) =   0.998630
...
cos( 82) =   0.139173
cos( 83) =   0.121869
cos( 84) =   0.104528
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.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

nicht nicht wie ich
lookup_sin[82] = 0.313228782433;
lookup_sin[83] = 0.9683644611;
lookup_sin[84] = 0.733190320073;
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.

Autor: Statistiker (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: JL (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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*.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist zb eine Diskussion zu diesem Thema

http://groups.google.com/group/comp.lang.c/browse_...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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_t...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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'?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.