Forum: Mikrocontroller und Digitale Elektronik pointer: const to non-const assignment


von mcrex (Gast)


Lesenswert?

Hallo liebe Forumnutzer,
ich benötige dringend eure Hilfe und hoffe dass jemand unter euc ist der 
sich erbarmt und dem einäugigen zur besseren Sicht verhift.
Das Problem ist, dass mein 8051er C Compiler immer an diesem Fehler 
stehenbleibt und ich schlicht nicht weiß wie ich das ausbügeln oder 
umgehen kann. Die Funktion soll ein paar Bytes an eine SD-Karte schicken 
um den Lese/Schreibvorgang zu initialisieren. Und so sieht das aus:
Fehlermeldung lautet : pointer: const to non-const assignment
1
/* Write Sector(s)                                                       */
2
3
#if _READONLY == 0
4
DRESULT disk_write (
5
  BYTE drv,      /* Physical drive nmuber (0..) */
6
  const BYTE *buff,  /* Data to be written */
7
  DWORD sector,    /* Sector address (LBA) */
8
  UINT count      /* Number of sectors to write  */
9
)
10
{
11
  if (drv || !count) return RES_PARERR;
12
  if (Stat & STA_NOINIT) return RES_NOTRDY;
13
14
  if (count == 1)/* Single block write */
15
  {  
16
@@@@@an dieser stelle@@@ if(!SD_writeSingleBlock(buff, sector)) count = 0;
17
    
18
  }
19
  else/* Multiple block write */
20
  {              
21
@@@@@an dieser stelle@@@ if(!SD_writeMultipleBlock (buff, sector, count)) count = 0;
22
  }
23
24
  return count ? RES_ERROR : RES_OK;
25
}
26
#endif /* _READONLY */

1
/* Prototypes for disk control functions */
2
3
DSTATUS disk_initialize (BYTE);
4
DSTATUS disk_status (BYTE);
5
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
6
#if  _READONLY == 0
7
DRESULT disk_write (BYTE, const BYTE*, DWORD, UINT);
8
#endif
9
DRESULT disk_ioctl (BYTE, BYTE, void*);
außerdem gehört das hier noch dazu
1
unsigned char SD_writeSingleBlock(unsigned char *buff, unsigned long startBlock);
2
unsigned char SD_writeMultipleBlock(unsigned char *buff, unsigned long startBlock, unsigned long totalBlocks);
Ich bedanke mich im Voraus und hoffe dass jemand das ganz locker lösen 
kann :)

von Vlad T. (vlad_tepesch)


Lesenswert?

die lösung steht doch im Betreff:

mcrex schrieb:
> pointer: const to non-const assignment

mcrex schrieb:
> const BYTE *buff,  /* Data to be written */

deine funktion bekommt einen const Pointer und die gerufene Funktion 
erwearetet einen Non-Const-Pointer:

mcrex schrieb:
> unsigned char SD_writeSingleBlock(unsigned char *buff, unsigned long 
startBlock);
-------------------------------------------------^
> unsigned char SD_writeMultipleBlock(unsigned char *buff, unsigned long 
startBlock, unsigned long totalBlocks);
-------------------------------------------------^

dies wiederum scheint auf eine nachlässigkeit des Programmierers der 
SD-Routinen zurückzuführen zu sein, da normalerwesie in Ausgaberoutinen 
der Zu schriebende Puffer nicht verändert wird, könnte man ihn auch als 
solchen, nämlich const, kennzeichnen.

von FPGASchubser (Gast)


Lesenswert?

Entferne (testweise) das const aus disk_write(....) und natürlich auch 
in der funktion disk_write..

Du versuchst einen const pointer an eine funktion im RW - Modus zu 
übergeben... Da meckert der Compliler zu Recht....

Gruß
F.

von Vlad T. (vlad_tepesch)


Lesenswert?

FPGASchubser schrieb:
> Entferne (testweise) das const aus disk_write(....) und natürlich auch
> in der funktion disk_write..

sauberer wäre es wohl den Fehler an der Wurzel zu bereinigen. sonst 
gibts das selbe Problem eine Ebene höher eventuell wieder.

fazit: änder den Pointer im Prototyp und der zugehörigen Implmenetierung 
der SD_write... auf const unsigned char *buff

von Klaus K. (klkl)


Lesenswert?

mcrex schrieb:
> @@@@@an dieser stelle@@@ if(!SD_writeSingleBlock(buff, sector)) count = 0;

Hallo

bekommst du das mit einem
---
if(!SD_writeSingleBlock((unsigned char *)buff, sector)) count = 0;
---
in den Griff? Casten (so nennt man das) ist aber meistens unschön.

Du musst dir aber überlegen wozu die const-Geschickte gedacht ist. Warum 
verlangt eine Funktion SD_writeSingleBlock nach einem nicht-const buff? 
Wird dieser durch die Funktions geändert?

Gruß Klaus

von Vlad T. (vlad_tepesch)


Lesenswert?

const wegcasten ist böse

von Adrian C. (knechtrootrecht)


Lesenswert?

herzlichen Dank erstmal!
Ich habe jetzt einfach das const vor dem
1
 const BYTE *buff,
entfernt folge dessen ist:

Bad actual argument type
an diese Stelle:
1
 /* Write Sector(s)                                                       */
2
3
#if _READONLY == 0
4
DRESULT disk_write (
5
  BYTE drv,      /* Physical drive nmuber (0..) */
6
  BYTE *buff,  /* Data to be written */
7
  DWORD sector,    /* Sector address (LBA) */
8
  UINT count      /* Number of sectors to write  */
9
)
10
{   <-----@@@@@@@@@@@genau hier@@@@@@@@q
11
  if (drv || !count) return RES_PARERR;
12
  if (Stat & STA_NOINIT) return RES_NOTRDY;
13
14
  if (count == 1)/* Single block write */
15
  {  
16
    if(!SD_writeSingleBlock(buff, sector)) count = 0;
17
    
18
  }
19
  else/* Multiple block write */
20
  {              
21
    if(!SD_writeMultipleBlock (buff, sector, count)) count = 0;
22
  }
23
24
  return count ? RES_ERROR : RES_OK;
25
}
26
#endif /* _READONLY */

von FPGASchubser (Gast)


Lesenswert?

Mann - Du musst es an zwei Stellen ändern !!!!

Auch das Prototype ändern.... und das nur zum Test...

von Adrian C. (knechtrootrecht)


Lesenswert?

Ein herzliches danke schön an Alle die sich die Mühe gemacht haben mir 
zu helfen. Ich werde zunächst die Lösung vom Klaus Kloos nehmen, 
zumindest findet sie der Copiler schon mal gut.

By the way.
Mein blöder Ride7 sagt jetzt dass ich die 8kB erreicht bzw überschritten 
habe und verweigert das kompilieren. Hat jemand eine Empfehlung für eine 
ToolCHain ohne diese Beschränkung.

von jb (Gast)


Lesenswert?

>Ich werde zunächst die Lösung vom Klaus Kloos nehmen,
>zumindest findet sie der Copiler schon mal gut.

Damit gräbste dir schön dein eignes Codegrab. Mach's doch gescheid!

gruß jb

von Adrian C. (knechtrootrecht)


Lesenswert?

wie wäre es denn deiner Ansicht nach gescheid und was genau ist schlecht 
an kloos´s lösung?

von Karl H. (kbuchegg)


Lesenswert?

Adrian Calota schrieb:
> wie wäre es denn deiner Ansicht nach gescheid

Das hier
1
unsigned char SD_writeSingleBlock(unsigned char *buff, unsigned long startBlock);

muss zu
1
unsigned char SD_writeSingleBlock(const unsigned char *buff, unsigned long startBlock);

werden.
Dann muss in der Implementierung das ebenfalls entsprechend geändert 
werden. Und es ist wahrscheinlich, das das noch weitere Kreise ziehen 
wird.

Das const macht die Zusicherung: "Lieber Aufrufer, ich werde deine Daten 
nicht verändern". Für eine Schreibfunktion ist das auch vernünftig, denn 
eine Schreibfunktion hat die Daten nicht zu verändern, die ich ihr gebe. 
Nur muss das dann aber auch komplett durchgezogen werden.

Mit einem Cast versteckst du das alles. So nach dem Muster:
Die Funktion disk_write macht zwar diese Zusicherung, kümmert sich 
allerdings einen Sch...Dreck darum, ob die Funktionen die es dazu 
benutzt, dann auch wirklich einhalten.
Const hat seinen Sinn, es einfach wegzucasten ist nicht die feine 
englische Art. Manchmal kann man das nicht anders machen, weil man den 
Source Code nicht hat und daher auch nicht ändern kann. Wenn man den 
Code allerdings zur Verfügung hat, dann zieht man das einmal durch und 
hat Ruhe.
Und natürlich: Der COmpiler kann das tun, was er im Rahmen seiner 
Möglichkeit am besten kann: Überwachen ob der Programmierer keinen 
Sch... baut.

von Adrian C. (knechtrootrecht)


Lesenswert?

an: Karl Heinz Buchegger
Nun, hierfür bedanke ich mich natürlich nochmals. Ich habe dies jetzt so 
geändert und natürlich akzeptiert der Kompiler das so. Dass die 
Schreibfunktion in  dem Fall besser nicht unvorhergesehenerweise 
überschrieben werden können darf ist sehr wichtig, vermute ich.
Merci @ all

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.