Pages: [1]   Go Down
Author Topic: Funktion Overload  (Read 436 times)
0 Members and 1 Guest are viewing this topic.
Germany, BW
Offline Offline
Sr. Member
****
Karma: 7
Posts: 302
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hab ein kleines Problem mit dem Überladen.
Folgende Funktionen existiern:
Code:
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)?
Logged

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3480
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1) Konstanten kann man auch explizit definieren:

Code:
const uint8_t typed_zero = 0;

2) Warum nicht mit Suffix:
http://arduino.cc/de/Reference/IntegerConstants
Logged

Check out my experiments http://blog.blinkenlight.net

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Germany, BW
Offline Offline
Sr. Member
****
Karma: 7
Posts: 302
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Write_Data(typed_zero,typed_zero);
Das ist aber auch unschön  smiley-sad

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...
« Last Edit: June 21, 2013, 10:40:26 am by mde110 » Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  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:
  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.
Logged

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3480
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Check out my experiments http://blog.blinkenlight.net

Pages: [1]   Go Up
Jump to: