deprecated conversion

#6991270
Lesenswert?

Demo Code von Microchip Technology Incorporated:
1
/* ----------------------------------------------------------------
2
Demo Code
3
This code example is used to continuously send the 'Hello World!' string through USART. A string is sent character by character. The ‘USART1_sendString’ function calls the ‘USART1_sendChar’ function for each character in the ‘Hello Word!’ string. Before sending each character, the ‘USART1_sendChar’ function waits for the previous character transmission to be completed. This is done by polling the Data Register Empty Interrupt Flag, DREIF, from the STATUS register until it is set.
4
------------------------------------------------------------------*/
5
#define F_CPU 3333333
6
#define USART1_BAUD_RATE(BAUD_RATE) ((float)(F_CPU * 64 / (16 * (float)BAUD_RATE)) + 0.5)
7
#include <avr/io.h>
8
#include <util/delay.h>
9
#include <string.h>
10
void USART1_init(void);
11
void USART1_sendChar(char c);
12
void USART1_sendString(char *str);
13
void USART1_init(void)
14
{
15
 PORTC.DIR &= ~PIN1_bm;
16
 PORTC.DIR |= PIN0_bm;
17
 
18
 USART1.BAUD = (uint16_t)USART1_BAUD_RATE(9600);
19
 USART1.CTRLB |= USART_TXEN_bm;
20
}
21
void USART1_sendChar(char c)
22
{
23
 while (!(USART1.STATUS & USART_DREIF_bm))
24
 {
25
  ;
26
 } 
27
 USART1.TXDATAL = c;
28
}
29
void USART1_sendString(char *str)
30
{
31
 for(size_t i = 0; i < strlen(str); i++)
32
 {
33
  USART1_sendChar(str[i]);
34
 }
35
}
36
int main(void)
37
{
38
 USART1_init();
39
 
40
 while (1)
41
 {
42
  USART1_sendString("Hello World!\r\n");
43
  _delay_ms(500);
44
 }
45
}
https://ww1.microchip.com/downloads/en/Appnotes/TB3216-Getting-Started-with-USART-DS90003216.pdf

Der Compiler von Microchip Technology Incorporated bemängelt aber die 
Zeile
1
 USART1_sendString("Hello World!\r\n");
mit
1
Warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

Wie wäre es dann richtiger?
Persönliche Seite #6991299
Lesenswert?

Richtig wäre es, wenn "USART1_sendString" ein Argument vom Typ "const 
char*" übernehmen würde. Schließlich sollte es den Text nicht verändern.
1
void USART1_sendString(const char *str)
2
{
3
 for(size_t i = 0; i < strlen(str); i++)
4
 {
5
  USART1_sendChar(str[i]);
6
 }
7
}

Allerdings wird hier strlen in jedem Durchlauf aufgerufen, d.h. super 
ineffizient. Viel besser geht es so:
1
void USART1_sendString(const char *str)
2
{
3
 for(const char* p = str; *p != '\0'; ++p)
4
 {
5
  USART1_sendChar(*p);
6
 }
7
}

Weil es ja um AVR geht, wäre es natürlich noch besser den String nur im 
Flash abzulegen.

Falls du mal den Fall hast dass du eine Funktion wie USART1_sendChar 
hast die den String tatsächlich ändert, muss man eine Kopie des Strings 
im RAM (hier: auf dem Stack) anlegen:
1
char str [] = "Hello World!\r\n";
2
USART1_sendString(str);

Hier ist also wieder schön zu sehen, dass die Mikrocontroller-Hersteller 
desaströse Code-Qualität produzieren, und Microchip ist ganz vorne 
dabei.
#6991343
Lesenswert?

Niklas G. schrieb:
> Allerdings wird hier strlen in jedem Durchlauf aufgerufen, d.h. super
> ineffizient.

Ab welcher Stringlänge fängt das an ineffizient zu werden, wenn die 
Baudrate 9600 ist?

Niklas G. schrieb:
> Hier ist also wieder schön zu sehen, dass die Mikrocontroller-Hersteller
> desaströse Code-Qualität produzieren, und Microchip ist ganz vorne
> dabei.
Das ist bei diesem Beispiel etwas übertrieben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren