Go Down

Topic: Funktion Overload (Read 509 times) previous topic - next topic

mde110

Hab ein kleines Problem mit dem Überladen.
Folgende Funktionen existiern:
Code: [Select]

void Write_Data(uint8_t Data);
void Write_Data(uint8_t Byte1, uint8_t Byte2);
void Write_Data(uint8_t* Bytes, uint8_t Count);


Bei Write_Data(0,0); sagt der Compiler: error: call of overloaded 'Write_Data(int, int)' is ambiguous
Bei Write_Data(0x00,0x00); sagt der Compiler: error: call of overloaded 'Write_Data(int, int)' is ambiguous
Bei Write_Data(1,0); compiliert er
Bei Write_Data(0x01,0); compiliert er

Warum erkennt er zwei Nullen als Int?
Wie kann ich das Problem lösen (Schön und ohne typecast)?

Udo Klein

1) Konstanten kann man auch explizit definieren:

Code: [Select]

const uint8_t typed_zero = 0;


2) Warum nicht mit Suffix:
http://arduino.cc/de/Reference/IntegerConstants
Check out my experiments http://blog.blinkenlight.net

jurs


Warum erkennt er zwei Nullen als Int?


Das ist nicht das Problem.

Das Problem ist, dass "0" auch für einen NULL-Pointer stehen kann.

Und dann kann der Compiler nicht mehr entscheiden, was er aufrufen soll:

Gilt der Aufruf für zwei Bytes:
void Write_Data(uint8_t Byte1, uint8_t Byte2);

Oder gilt der Aufruf für einen Pointer (NULL-Pointer) und ein Byte:
void Write_Data(uint8_t* Bytes, uint8_t Count);


Wie kann ich das Problem lösen (Schön und ohne typecast)?


Entweder mehrdeutige Aufruf-Interfaces beim Überladen von Funktionen komplett vermeiden.

Oder statt Funktionen mit Konstanten aufzurufen, die zu übergebenden Werte an Variablen zuweisen und der Funktion beim Aufruf die Variablen übergeben (Achtung. RAM-Speicherbedarf).

Oder eben die Mehrdeutigkeit beim Aufruf per Typecasting aufheben.

mde110

#3
Jun 21, 2013, 05:37 pm Last Edit: Jun 21, 2013, 05:40 pm by mde110 Reason: 1
Code: [Select]
Write_Data(typed_zero,typed_zero);
Das ist aber auch unschön  :(

Danke Jurs, jetzt verstehe ich es auch, wie der Compiler denkt.
Habe schon vermutet, dass ich etwas nicht beachtet habe...

Werde dann wohl die Funktion umbenennen müssen. Mal sehen...

jurs


Danke Jurs, jetzt verstehe ich es auch, wie der Compiler denkt.


Tja, der NULL Pointer ist als einziger Pointer ohne Typecasting zuweisungskompatibel zu jedem anderen Pointer, egal ob char-Pointer, byte-Pointer oder WasWeissIch-Pointer:
Code: [Select]

  char* char_ptr;
  byte* byte_ptr;
  char_ptr=0;
  byte_ptr=0;

Das frisst der Compiler einwandfrei (von der Sinnhaftigkeit mal abgesehen).
Aber versuch da mal was anderes als 0 zuzuweisen.
Schon meckert der Compiler wegen Inkompatibilität der Zuweisung.
Der NULL-Pointer ist zuweisungstechnisch schon einzigartig.

Für andere Zuweisungen mit Ausnahme des Nullpointers benötigst Du Typecasting:
Code: [Select]

  char_ptr=(char*)1;
  byte_ptr=(byte*)2;


Und weil der Nullpointer zuweisungstechnisch so einzigartig ist, bekommst Du mit Deinem überladenen Funktionsaufruf Probleme, wenn der erste Parameter sowohl eine Byte-0 als auch ein Nullpointer sein kann, weil Du beide Interfaces vorgesehen hast.

Ich glaube, das mit dieser besonderen Zuweisungskompatibilität des Nullpointers ist nicht einmal eine reine Arduino-Angelegenheit, das gilt auch für andere C-Compiler.

Udo Klein

Quote

Oder statt Funktionen mit Konstanten aufzurufen, die zu übergebenden Werte an Variablen zuweisen und der Funktion beim Aufruf die Variablen übergeben (Achtung. RAM-Speicherbedarf).


Konstanten verbrauchen nie mehr Speicher als die Literale direkt hinzuschreiben. Jeder moderne Compiler kann sowas besser optimieren. Es gibt eher Fälle bei denen es umgekehrt ist, d.h. die Konstanten brauchen im Zweifelsfall weniger Ram als die Literale.
Check out my experiments http://blog.blinkenlight.net

Go Up