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


von Daniel G. (motello)


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:
1
typedef struct {
2
   const char *name;
3
   int (*open_r )( struct _reent *r, const char *path, int flags, int mode );
4
   int (*close_r )( struct _reent *r, int fd );
5
   long (*write_r ) ( struct _reent *r, int fd, const char *ptr, int len );
6
   long (*read_r )( struct _reent *r, int fd, char *ptr, int len );
7
} 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

von (prx) A. K. (prx)


Lesenswert?

Schreib ein
  struct _reent;
vor das Typedef.

von Daniel G. (motello)


Lesenswert?

Ja, so einfach kanns sein - es funktioniert! Danke"

von Daniel G. (motello)


Lesenswert?

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

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

von Karl H. (kbuchegg)


Lesenswert?

Daniel G. schrieb:
> Also das Davorschreiben von
1
struct _reent;
 hat nur scheinbar
> geholfen. Ich musste stattdessen
1
#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)
>
1
> int rs232_close_r (struct _reent *r, int fd) {
2
>     /* return not supported */
3
>     r->errno = ENOTSUP;
4
>     return -1;
5
> }
6
>
> 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?

von Daniel G. (motello)


Lesenswert?

hier der code:
1
#include "stubs.h"
2
#include "at91sam9260.h"
3
#include "main.h"
4
#include <reent.h>
5
#include <errno.h>
6
7
//struct _reent;
8
9
extern void _irq_on();
10
extern void _irq_off();
11
12
/* Write DBGU register */
13
static inline void write_dbgu(unsigned int offset, const unsigned int value)
14
{
15
  writel(value, offset + AT91C_BASE_DBGU);
16
}
17
18
/* Read DBGU registers */
19
static inline unsigned int read_dbgu( unsigned int offset)
20
{
21
  return readl(offset + AT91C_BASE_DBGU);
22
}
23
24
long rs232_write_r (struct _reent *r, int fd, const char *ptr, int len) {
25
26
  int i=0;
27
  
28
  _irq_off();
29
  while (ptr[i] != '\0') {
30
    while ( !(read_dbgu(DBGU_CSR) & AT91C_US_TXRDY) );
31
    write_dbgu(DBGU_THR, ptr[i]);
32
    i++;
33
  }
34
  _irq_on();
35
36
  return len;
37
}
38
39
long rs232_read_r (struct _reent *r, int fd, char *ptr, int len) {
40
  /* return not supported */
41
  r->errno = ENOTSUP;
42
  return -1;
43
}
44
45
int rs232_open_r (struct _reent *r, const char *path, int flags, int mode) {
46
  /* return not supported */
47
  r->errno = ENOTSUP;
48
  return -1;
49
}
50
  
51
int rs232_close_r (struct _reent *r, int fd) {
52
  /* return not supported */
53
  r->errno = ENOTSUP;
54
  return -1;
55
}
56
57
/* device operations table */
58
const devoptab_t devoptab_rs232 = {
59
  "rs232", rs232_open_r, rs232_close_r, rs232_write_r, rs232_read_r
60
};

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

von Stefan E. (sternst)


Lesenswert?

Dann müssten wir mal wissen, mit was ENOTSUP ersetzt wird.

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


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.

von (prx) A. K. (prx)


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.

von Daniel G. (motello)


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

von (prx) A. K. (prx)


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++.

von Daniel G. (motello)


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?

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


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.

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.