Forum: Mikrocontroller und Digitale Elektronik Makro für sprintf ((char*) s , "abc");


von Timo P (Gast)


Lesenswert?

Hallo!

gerne würde ich statt:

sprintf(s, "abc");

folgendes schreiben, um die Warnung des Compilers zu eliminieren:

sprintf( (char *) s, "abc");

Meine Idee ist ein define dafür.(Sollte Makro heißen?)

#define sprintf(s,"abc");       sprintf((char *)s,"abc");


Sowas kann aber nicht funktionieren, weil ich nie vorher weiß,

1) wie viele Parameter ich übergebe
2) abc auch anders sein könnte

Wie kann ich nun ein dynamischeres Makro erzeugen?

von Peter (Gast)


Lesenswert?

Timo P schrieb:
> sprintf(s, "abc");
> folgendes schreiben, um die Warnung des Compilers zu eliminieren:
welche warnung, wenn man es richtig macht kommt da keine Warnung

von Klaus W. (mfgkw)


Lesenswert?

Im Standard-Präprozessor kann man keine Variable Anzahl von Parametern 
angeben.
Auch wenn es (nicht portabel) geht, wie z.B.
http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Variadic-Macros.html#Variadic-Macros
, macht es normalerweise mehr Sinn, ordentlich zu programmieren.
Dann braucht man nicht mit dem PP irgendwelche Warnungen unterdrücken.

von Timo P (Gast)


Lesenswert?

unterdrücken?? Das will ich ja nicht!

die Funktion erwartet von mir ein char*. Ich habe aber ein char s[38];

also muss ich einen typecast machen im Funktionsaufruf:

sprintf((char*)&s,"abc");

diesen will ich aber nicht jedes mal wenn ich sprintf nutze schreiben. 
Was kann ich dagegen tun? Grundsätzlich nicht s als:

 char s[38]; sondern als char * s[38]; anlegen?

Peter schrieb:
> welche warnung,

Warnung: argument 1 of sprintf discards qualifiers from pointer target 
type

Peter schrieb:
> wenn man es richtig macht kommt da keine Warnung

Wie soll ich es denn "richtig" machen

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Timo P schrieb:
> die Funktion erwartet von mir ein char*. Ich habe aber ein char s[38];
>
> also muss ich einen typecast machen im Funktionsaufruf:
>
> sprintf((char*)&s,"abc");

Nein. Das musst Du nicht. Das funktioniert auch so.

Wenn Du da eine Warnung bekommst, dann bekommst Du die aus einem 
anderen Grund.

Poste ein exaktes Quelltextbeispiel und die genaue Meldung des 
Compilers.

von Klaus W. (mfgkw)


Lesenswert?

Timo P schrieb:
> Was kann ich dagegen tun? Grundsätzlich nicht s als:
>
>  char s[38]; sondern als char * s[38]; anlegen?

das ganz bestimmt nicht.

von Timo P (Gast)


Lesenswert?

functions.c:
1
#include main.h
2
3
check_command()
4
{
5
  if(strstr((char*)buffer_,"SENSORS\n"))  
6
  {
7
    kill_buffer_();
8
    sprintf(s,"SENSORS:%02d\n",AVAILABLE_SENSORS);
9
    uart_puts(s);
10
    sei();
11
  }
12
}

uart.c:
1
void uart_putc(unsigned char byte)
2
{
3
  while(!(UCSRA&(1<<UDRE)));//delay til data register empty
4
  UDR=byte;   // sending one byte
5
}
6
7
// send string with /0
8
void uart_puts(char *s) 
9
{
10
    while (*s!=0) 
11
  {
12
     uart_putc(*s);
13
      s++;
14
   }
15
    uart_putc(0); //endmark 0
16
}

WARNING:../functions.c:72: warning: passing argument 1 of 'sprintf' 
discards qualifiers from pointer target type

von Timo P (Gast)


Lesenswert?

Evtl. liegt es daran, dass ich im main.c

char s[38]; anlege, es in der uart.c und functions.c als extern 
deklariere?

von Klaus W. (mfgkw)


Lesenswert?

Schwer zu sagen, wenn man die relevanten Teile nicht sieht.

Deshalb sage ich einfach mal: bestimmt!

von Timo P (Gast)


Angehängte Dateien:

Lesenswert?

Ist für nen Atmega16 via GCC + AVR-Studio kompiliert.

Hier ist das Projekt...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na, da haben wir doch das Problem:

functions.c
1
extern volatile char         ssid[37], key[37], s[33];

s ist als volatile deklariert, damit aber rechnet sprintf nicht.

von Timo P (Gast)


Lesenswert?

Wann genau habe ich volatile nötig?

Ich weiß, dass volatile notwendig ist, wenn man die varialbe aus einem 
Interrupt heraus verändern möchte. Gibt es noch weitere praktische 
Anwendungen von volatile?

von Peter (Gast)


Lesenswert?

Timo P schrieb:
> Ich weiß, dass volatile notwendig ist, wenn man die varialbe aus einem
> Interrupt heraus verändern möchte.
nein, nur wenn sie im Interrupt geändert wird und in der Main genutzt 
wird. Das sich bei dir um ein zeiger handelt ist auch noch die Frage ob 
du den Zeiger selber änderst oder ob du das Änderst worauf der Zeiger 
zeigt.

von Johnny B. (johnnyb)


Lesenswert?

Ich würde sagen nicht mal unbedingt im Interrupt ist volatile notwendig. 
Kommt aber auf den Optimizer darauf an.

Volatile ist dann notwendig, wenn sich der Wert einer Variablen ändern 
kann, ohne dass Dein Programmcode dies verursacht hat. Das ist 
insbesondere bei Timerregistern oder Eingangsports des Mikrocontrollers 
der Fall. Da musst Du dem Compiler mitteilen, dass er hier die Zustände 
immer neu einlesen muss und das Einlesen nicht wegoptimieren darf.

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.