Inline bei Call by Reference

Gast #3379499
Lesenswert?

Hallo,

ich möchte eine generische Funktion mit dem Zusatz Inline 
implementieren, diese Funktion soll den Zugriff auf ein Array ausführen. 
Jetzt Frage ich mich, wie der Compiler den Code ersetzt. Muss ich den 
Übergabeparameter als Call by Reference durchführen ( müsste dann auf 
NULL Pointer prüfen) oder geht auch Call by Value. Die Struktur hätte 
diese Form:

struct array
{
   struct liste* data;  /* pointer aufs erste elment vom Array*/
   char anzahl_data_elemente;
   char max_anzahl_data_elemente;
}

inline void ArrayZugriff( struct array* container, char element_id, 
struct  list* rueckgabewert)
{
   if( element_id < max_anzahl_data_elemente)
        rueckgabewert = container->data[element_id];
}

main()
{
   .
   .
   .
   ArrayZugriff( &container, element_id, &rueckgabewert)

}
#3379548
Lesenswert?

Ich sach mal so:

Da der gcc vom Programmierer vorgeschlagenes inlining schlicht 
ignoriert, und einfach dann inlined, wenn er das selber für richtig 
hält, ist die Frage zwar interessant, aber ansonsten belanglos.

Und müssen musst du gar nichts.

Bleibt noch die Frage, was du gegen Funktionen hast, die ihr Ergebnis 
per Return zurückgeben.

Oliver
#3379550
Lesenswert?

Frank schrieb:
> Hallo,
>
> ich möchte eine generische Funktion mit dem Zusatz Inline
> implementieren, diese Funktion soll den Zugriff auf ein Array ausführen.
> Jetzt Frage ich mich, wie der Compiler den Code ersetzt. Muss ich den
> Übergabeparameter als Call by Reference durchführen ( müsste dann auf
> NULL Pointer prüfen) oder geht auch Call by Value.

call bei value ist ok.
stell dir einfach den Code an der Aufrufstelle eingesetzt vor und dann 
optimierst du selber mal daran rum. Du wirst sehen, das ist nicht 
schwer, die Argumente los zu werden.
Wenn du das auf dem Papier in 30 Sekunden kannst, dann kann das dein 
Compiler schon lange.

Das allerdings
1
inline void ArrayZugriff( struct array* container, char element_id, struct list* rueckgabewert) {
2
if( element_id < max_anzahl_data_elemente)
3
rueckgabewert = container->data[element_id];
4
}
ist keine so gute Idee. Was hast du gegen Returnwerte?
Dann hätte dich nämlich der Compiler auch darauf aufmerksam gemacht, 
dass du auch im Fehlerfall einen Returnwert brauchst.
#3379582
Lesenswert?

Frank schrieb:
> Wie würdest du es machen
> @Karl Heinz

erst mal musst du eine Strategie ausgeben, welcher Wert geliefert werden 
soll, bzw. was passieren soll, wenn der Index tatsächlich zu groß ist.

Einen Fehler abzufangen ist gut. Aber der Aufrufer der Funktion weiß 
nichts davon, dass da ein Fehler abgefangen wurde und er daher mit dem 
gelieferten nichts anfangen kann. Wie ist dann in so einem Fall weiter 
zu verfahren?
Gast #3379627
Lesenswert?

Hi,

wenn mit einem falschen index zugegriffen wird... Soll es ein Default 
wert zurückliefen.
Fur mich ist eigentlich von Interesse, ob man die Übergabeparameter und 
der Return wert als Call by Value übergeben kann.
Hintergrund... Eine Funktion soll über c files hinweg verwendet werden 
und als Get funktion Daten liefern. Dabei kann es vorkommen, das diese 
Get Funktion 2000mal aufgerufen wird und somit ein Inline von Vorteil 
wäre. ( Lauzeit)
#3380070
Lesenswert?

Frank schrieb:
> Fur mich ist eigentlich von Interesse, ob man die Übergabeparameter und
> der Return wert als Call by Value übergeben kann.

Rolf Magnus schrieb:
> Warum sollte man das nicht können?

Also mir raucht da der Schädel:
 Return-Wert (=Rückgabe) übergeben? Als Wert? Was kommt denn da wie 
zurück?

Die Billigvariante um ein Element aus einem Array zu erhalten, geht doch 
so:
1
x = a[i];

Meiner Meinung sollte sich an dem 'Aussehen' durch die Verwendung einer 
Funktion nicht viel ändern.
1
x = f(a[i], /*weitere Parameter */);

PS: Wenn's uuunbedingt 'inline' sein muss und es nur um die Indexprüfung 
geht, würde ich mal den Begriff 'Makro' in den Raum werfen.
Gast #3380226
Lesenswert?

Ralf G. schrieb:
> Rolf Magnus schrieb:
>> Warum sollte man das nicht können?
>
> Also mir raucht da der Schädel:
>  Return-Wert (=Rückgabe) übergeben? Als Wert? Was kommt denn da wie
> zurück?

Na der Wert eben. Wo ist das Problem?

> Die Billigvariante um ein Element aus einem Array zu erhalten, geht doch
> so:x = a[i];
>
> Meiner Meinung sollte sich an dem 'Aussehen' durch die Verwendung einer
> Funktion nicht viel ändern.x = f(a[i], /*weitere Parameter */);

Was er machen will, scheint eher sowas zu sein:
1
x = p->a[i];
und daraus soll ein:
1
x = f(p, i);
werden.

> PS: Wenn's uuunbedingt 'inline' sein muss und es nur um die Indexprüfung
> geht, würde ich mal den Begriff 'Makro' in den Raum werfen.

Ein Makro hat hier allerings keinerlei Vorteile gegenüber einer 
inline-Funktion, bringt dafür aber die üblichen zusätzlichen Gefahren 
mit sich.
#3380239
Lesenswert?

Frank schrieb:
> Hi,
>
> wenn mit einem falschen index zugegriffen wird... Soll es ein Default
> wert zurückliefen.

Gut.

Wo liegt dann das Problem bei
1
inline struct list ArrayZugriff( struct array* container, char element_id ) __attribute__((always_inline))
2
{
3
  if( element_id < container-> anzahl_data_elemente)
4
    return container->data[element_id];
5

6
  return defaultValue;
7
}

das präsentierst du dem Compiler so, dass er inlinen kann, und überlässt 
den Rest dem Compiler.
#3380327
Lesenswert?

Ralf G. schrieb:

>> Na der Wert eben. Wo ist das Problem?
>
> Irgendwas habe ich da wohl falsch verstanden:
>
1
> void f(int x)
2
> {
3
>   x = 42;
4
> };
5
> // ...
6
> int y = 12;
7
> f(y);
8
> // ...
9
>
> Das wäre für mich jetzt die Übergabe als Wert. Da sehe ich nichts
> zurückkommen.

1
int f( int x )
2
{
3
  return 2*x;
4
}
5

6
int main()
7
{
8
  int y;
9

10
  y = f( 5 );
11
}
Gast #3380481
Lesenswert?

Ralf G. schrieb:
> Rolf Magnus schrieb:
>> Na der Wert eben. Wo ist das Problem?
>
> Irgendwas habe ich da wohl falsch verstanden:
> void f(int x)
> {
>   x = 42;
> };
> // ...
> int y = 12;
> f(y);
> // ...
> Das wäre für mich jetzt die Übergabe als Wert.

Richtig.

> Da sehe ich nichts zurückkommen.

Warum sollte es? Du übergibst ja per Wert. Du verwechselst vielleicht 
Wert mit Objekt. 12 ist z.B. ein Wert. Einen Wert kann man nicht ändern. 
Ich kann z.B. nicht sagen, 12 soll jetzt 42 sein. Man kann nur in eine 
Variable einen anderen Wert schreiben. Ich kann also sagen, x soll jetzt 
den Wert 42 enthalten. x ist aber ein anderes Objekt als y. Daher wird 
sich y nicht auf magische Weise ändern, nur weil man x ändert.
Wenn du stattdessen "by-reference" übergibst, ist y eine Referenz auf x, 
wodurch sich die Änderungen an y auch entsprechend auf x auswirken.
#3380544
Lesenswert?

Rolf Magnus schrieb:
> Warum sollte es? Du übergibst ja per Wert.
Das ist mir alles klar.

Frank schrieb:
> Muss ich den
> Übergabeparameter als Call by Reference durchführen ( müsste dann auf
> NULL Pointer prüfen) oder geht auch Call by Value.

Karl Heinz schrieb:
> call bei value ist ok.

Ich werde nur aus diesen beiden Aussagen nicht ganz schlau, denn

Ralf G. schrieb:
> Irgendwas habe ich da wohl falsch verstanden:
bzw. interpretiere in den Eröffnungspost was falsches hinein.
#3380699
Lesenswert?

Ralf G. schrieb:
>> Irgendwas habe ich da wohl falsch verstanden:
> bzw. interpretiere in den Eröffnungspost was falsches hinein.

Der TE hat zwei Probleme.

1. er sträubt sich gegen einen Returnwert und macht lieber call-by-(non 
const)-reference. Das ist im wesentlichen eine Geschmacksfrage.

2. er glaubt, die Signatur seiner Funktion, insbesondere die Frage ob er 
call-by-value oder call-by-reference verwendet, hätte irgendwas mit der 
inline-barkeit zu tun. Hat es nicht.

Wenn der Compiler eine Funktion inlined, dann bleibt die Semantik 
komplett erhalten. Und die Details der Parameter/Returnwertübergabe 
verlieren jegliche Bedeutung. Wie denn auch sonst?


XL

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