www.mikrocontroller.net

Forum: Compiler & IDEs struct _reent' declared inside parameter list


Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich baue gerade die nötigen stubs in mein Programm um Teile von Newlib 
zu nutzen. Abgeschaut habe ich mir das bei 
http://www.embedded.com/columns/9900512?_requestid=139525

Hierbei:
typedef struct {
   const char *name;
   int (*open_r )( struct _reent *r, const char *path, int flags, int mode );
   int (*close_r )( struct _reent *r, int fd );
   long (*write_r ) ( struct _reent *r, int fd, const char *ptr, int len );
   long (*read_r )( struct _reent *r, int fd, char *ptr, int len );
} devoptab_t;

...tritt folgender Fehler beim auf:

./header/stubs.h:18: warning: 'struct _reent' declared inside parameter 
list

Toolchain ist codesourcery, ich hoffe jemand kann helfen.

Grüße,
Daniel

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreib ein
  struct _reent;
vor das Typedef.

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, so einfach kanns sein - es funktioniert! Danke"

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das Davorschreiben von
struct _reent;
 hat nur scheinbar geholfen. Ich musste stattdessen
#include <reent.h>
 benutzen.

Ein weiteres Problem habe ich nun mit errno: (habe ich mir im oben 
verlinkten Artikel abgeschaut)
int rs232_close_r (struct _reent *r, int fd) {
    /* return not supported */
    r->errno = ENOTSUP;
    return -1;
}
errno.h ist included. Compiler meckert:
"error: expected identifier before '(' token"

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

Bewertung
0 lesenswert
nicht lesenswert
Daniel G. schrieb:
> Also das Davorschreiben von
struct _reent;
 hat nur scheinbar
> geholfen. Ich musste stattdessen
#include <reent.h>
 benutzen.

Um diesen Struct in Form eines Pointers zu verwenden brauchst du das 
nicht.
Wenn du dann allerdings über diesen Pointer auf Member zugreifen willst, 
muss klarerweise der exakte Aufbau der Strktur bekannt sein, da reicht 
dann eine Forward Deklaration nicht.

>
> Ein weiteres Problem habe ich nun mit errno: (habe ich mir im oben
> verlinkten Artikel abgeschaut)
>
> int rs232_close_r (struct _reent *r, int fd) {
>     /* return not supported */
>     r->errno = ENOTSUP;
>     return -1;
> }
> 
> errno.h ist included. Compiler meckert:
> "error: expected identifier before '(' token"

in welcher Zeile?
Poste bitte das komplette File und alles was dazu gehört.

Kann es sein, dass in der Zeile unmittelbar davor ein ';' fehlt?

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier der code:
#include "stubs.h"
#include "at91sam9260.h"
#include "main.h"
#include <reent.h>
#include <errno.h>

//struct _reent;

extern void _irq_on();
extern void _irq_off();

/* Write DBGU register */
static inline void write_dbgu(unsigned int offset, const unsigned int value)
{
  writel(value, offset + AT91C_BASE_DBGU);
}

/* Read DBGU registers */
static inline unsigned int read_dbgu( unsigned int offset)
{
  return readl(offset + AT91C_BASE_DBGU);
}

long rs232_write_r (struct _reent *r, int fd, const char *ptr, int len) {

  int i=0;
  
  _irq_off();
  while (ptr[i] != '\0') {
    while ( !(read_dbgu(DBGU_CSR) & AT91C_US_TXRDY) );
    write_dbgu(DBGU_THR, ptr[i]);
    i++;
  }
  _irq_on();

  return len;
}

long rs232_read_r (struct _reent *r, int fd, char *ptr, int len) {
  /* return not supported */
  r->errno = ENOTSUP;
  return -1;
}

int rs232_open_r (struct _reent *r, const char *path, int flags, int mode) {
  /* return not supported */
  r->errno = ENOTSUP;
  return -1;
}
  
int rs232_close_r (struct _reent *r, int fd) {
  /* return not supported */
  r->errno = ENOTSUP;
  return -1;
}

/* device operations table */
const devoptab_t devoptab_rs232 = {
  "rs232", rs232_open_r, rs232_close_r, rs232_write_r, rs232_read_r
};

Genau die drei Zeilen, die auf das member errno vom reent-struct 
zugreifen, werden bei den drei Fehlermeldungen: "error: expected 
identifier before '(' token" genannt.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann müssten wir mal wissen, mit was ENOTSUP ersetzt wird.

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

Bewertung
0 lesenswert
nicht lesenswert
Die Struktur reent hat kein Recht, eins ihrer Mitglieder "errno" zu
nennen.  errno ist per C-Standard ein Makro, der auf unbestimmte
Weise so expandiert, dass ein `modifiable lvalue that has type int'
daraus entsteht.  Ein solcher Makro kollidiert notwendigerweise mit
dem Versuch, ein Strukturelement `errno' zu benennen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
errno könnte ein Makro sein, das auf diese _reent struct zugreift. Wie 
ist errno definiert und wie _reent?

Unabhängig davon mir fällt die antike K&R-Deklaration von _irq_xxx auf.

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ich auch im Internet nichts gefunden habe, schreibe ich mal Bill 
Gatliff, den Autor des Artikels, an. In der Newlib Doku steht auch nix.

_irq_xxx habe ich selbst in assembler geschieben. Also könnte die 
Bezeichnung u.U. mit etwas kollidieren? Gibt es eine library funktion, 
die interrupts ein und ausschaltet oder bliebe mir eh nichts anderes 
übrig als selbst schreiben?

Grüße
Daniel

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel G. schrieb:

> _irq_xxx habe ich selbst in assembler geschieben. Also könnte die
> Bezeichnung u.U. mit etwas kollidieren?

Nix dagegen. Nur hast du, möglicherweise ohne es zu wissen, eine 
archaische Deklarationstechnik verwendet. So steht
 void f();
für eine Funktion mit beliebigen Parametern, jedoch
 void f(void);
für eine Funkion ohne Parameter. Es sei denn es ist C++.

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Idee ist mir noch gekommen:
Vielleicht ist Newlib ja gar nicht für reentrant functions compiliert. 
Ich habe die Toolchain nicht selbst compiliert und den Quelltext nicht, 
daher kann ich nicht im Makefile nachsehen.

Der Linker gibt folgende Fehler aus (Auszug), wenn ich ohne die 
Stub-Dateien weglasse:

/local_data/dageri/bin/codesourcery-armgcc-2008q1/bin/../lib/gcc/arm-non 
e-eabi/4.2.3/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o):  In 
function `_sbrk_r':
sbrkr.c:(.text+0x18): undefined reference to `_sbrk'
/local_data/dageri/bin/codesourcery-armgcc-2008q1/bin/../lib/gcc/arm-non 
e-eabi/4.2.3/../../../../arm-none-eabi/lib/libc.a(lib_a-writer.o):  In 
function `_write_r':
writer.c:(.text+0x20): undefined reference to `_write'
/local_data/dageri/bin/codesourcery-armgcc-2008q1/bin/../lib/gcc/arm-non 
e-eabi/4.2.3/../../../../arm-none-eabi/lib/libc.a(lib_a-closer.o):  In 
function `_close_r':

Dort ist schon von xxx_r die rede, also ist Newlib für reentrant 
functions compiliert!?! Oder wie kann ich es feststellen?

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

Bewertung
0 lesenswert
nicht lesenswert
> "error: expected identifier before '(' token"

Schick den ganzen Kram mal nur durch den Präprozessor (-E statt -c
im Compileraufruf), und guck dir an, was der in diesen Zeilen dann
hinein übersetzt.

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.