it-swarm.com.de

Was bedeutet ein Zeiger auf eine konstante Funktion?

Zeiger können als Zeiger auf veränderbare (nicht konstante) Daten oder als Zeiger auf konstante Daten deklariert werden.
Es können Zeiger definiert werden, die auf eine Funktion zeigen.

Meine Kollegen und ich diskutierten die Verwendung von "const" mit Zeigern und die Frage nach der Verwendung von const mit Funktionszeigern.

Hier sind einige Fragen:

  1. Was bedeutet ein Zeiger auf eine konstante Funktion im Vergleich zu einem Zeiger auf eine nicht konstante Funktion?
  2. Kann eine Funktion const sein?
  3. Kann eine Funktion nicht const (veränderlich) sein?
  4. Was ist die richtige (sichere) Syntax für die Übergabe eines Funktionszeigers?

Edit 1: Funktionszeigersyntax

typedef void (*Function_Pointer)(void); // Pointer to void function returning void.

void function_a(Function_Pointer p_func); // Example 1.
void function_b(const Function_Pointer p_func); // Example 2.
void function_c(Function_Pointer const p_func); // Example 3.
void function_d(const Function_Pointer const p_func); // Example 4.

Die obigen Deklarationen sind Beispiele für die Behandlung eines Funktionszeigers wie eines Zeigers auf einen intrinsischen Typ.

Ein Daten-, Variablen- oder Speicherzeiger ermöglicht die obigen Kombinationen.
Die Fragen sind also: Kann ein Funktionszeiger die gleichen Kombinationen haben und was bedeutet ein Zeiger auf eine konstante Funktion (wie Beispiel 2)?

23
Thomas Matthews

In C gibt es keine Funktion, bei der es sich um eine const-Funktion handelt. Ein Zeiger auf eine const-Funktion ist daher sinnlos (sollte nicht kompiliert werden, obwohl ich mit keinem bestimmten Compiler gesucht habe).

Beachten Sie, dass Sie zwar einen anderen Zeiger auf eine Funktion, einen Zeiger auf eine Funktion, die const zurückgibt, usw. haben können. Im Wesentlichen kann alles außer der Funktion selbst const sein. Betrachten wir einige Beispiele:

// normal pointer to function
int (*func)(int);

// pointer to const function -- not allowed
int (const *func)(int);

// const pointer to function. Allowed, must be initialized.          
int (*const func)(int) = some_func;

// Bonus: pointer to function returning pointer to const
void const *(*func)(int);

// triple bonus: const pointer to function returning pointer to const.
void const *(*const func)(int) = func.

Das Übergeben eines Zeigers auf eine Funktion als Parameter ist ziemlich einfach. Normalerweise möchten Sie einfach einen Zeiger auf den richtigen Typ übergeben. Ein Zeiger auf einen beliebigen Funktionstyp kann jedoch in einen Zeiger auf einen anderen Funktionstyp umgewandelt werden, dann auf seinen ursprünglichen Typ zurückgesetzt werden und den ursprünglichen Wert beibehalten.

45
Jerry Coffin

Gemäß der C-Spezifikation ( C99 , Abschnitt 6.7.3):

Die mit qualifizierten Typen verknüpften Eigenschaften sind nur für - Ausdrücke von Bedeutung, die lvalues ​​sind.

Wenn die Spezifikation "qualifizierte Typen" sagt, bedeutet dies, was mit dem Schlüsselwort const, restrict odervolatile definiert wurde. Snice-Funktionen sind keine l-Werte, das const-Schlüsselwort einer Funktion ist nicht aussagekräftig. Möglicherweise sehen Sie sich eine Art compilerspezifische Erweiterung an. Einige Compiler geben einen Fehler aus, wenn Sie versuchen, eine Funktion als const zu deklarieren.

Sind Sie sicher, dass Sie einen Zeiger auf eine konstante Funktion und nicht einen konstanten Zeiger auf eine Funktion betrachten (dh es ist der Zeiger das ist const, nicht die Funktion)?

Zu # 4: Siehe diese Anleitung für eine hilfreiche Übersicht über das Erstellen, Übergeben und Verwenden von Funktionszeigern.

6
bta

Unter C gibt es keine const-Funktion. const ist ein Typqualifizierer und kann daher nur zur Qualifizierung eines Typs und nicht einer Funktion verwendet werden. Vielleicht meinen Sie einen konstanten Zeiger auf eine Funktion oder einen nicht konstanten Zeiger auf eine Funktion?

In C++ können Methoden const sein. Wenn eine Methode const ist, bedeutet dies, dass sich das Objekt, das die Methode enthält, nach dem Aufruf dieser Methode in demselben Status befindet wie vor dem Aufruf der Methode (keine der Instanzvariablen [1] wurde geändert). Daher können Sie auf eine const-Methode und eine non-const-Methode verweisen. Diese Methoden unterscheiden sich.

Sie können einen Funktionszeiger in einer Argumentliste als retType (*variableName)(arguments) akzeptieren.

[1] Es sei denn, sie sind mutable.

2
greg

In C können die Funktionen canconst sein, wenn Sie sich in der Welt des GCC befinden! Funktionen können const durch die Verwendung von Attributen deklariert werden, die an Deklarationen von Funktionen und anderen Symbolen angehängt sind. Es wird im Grunde verwendet, um dem Compiler Informationen darüber zu liefern, was die Funktion bewirkt, auch wenn der Rumpf nicht verfügbar ist, so dass der Compiler damit einige Optimierungen durchführen kann.

Eine konstante Funktion wird im Allgemeinen als pure-Funktion definiert. 

Eine reine Funktion ist eine Funktion, die praktisch keine Nebenwirkung hat. Diese Bedeutet, dass reine Funktionen einen Wert zurückgeben, der auf der Grundlage von Gegebenen Parametern und des globalen Speichers berechnet wird, den Wert einer Anderen globalen Variablen jedoch nicht beeinflussen kann. Reinen Funktionen kann ein Rückgabewert (.____.) Nicht vernünftig sein (d. H. Einen Rückgabewert vom Typ ungültig haben).

Und jetzt können wir definieren, was eine const-Funktion ist,

Eine reine Funktion, die nicht auf den globalen Speicher, sondern nur auf die - Parameter zugreift, wird als konstante Funktion bezeichnet. Dies liegt daran, dass die Funktion , Die nicht mit dem Zustand des globalen Speichers zusammenhängt, immer Denselben Wert zurückgibt, wenn dieselben Parameter angegeben werden. Der Rückgabewert Wird somit direkt und ausschließlich aus den Werten der angegebenen Parameter abgeleitet.

Hier bedeutet const nichts über Funktionsveränderlichkeit. Es ist jedoch eine Funktion, die das globale Gedächtnis nicht berührt. Sie können solchen Funktionen normale Zeiger zuweisen. Auf jeden Fall wird der Code-Bereich im Allgemeinen RO sein (er vergisst eine Zeit lang selbstmodifizierenden Code) und kann nicht über den normalen Zeiger geändert werden.

Lesen Sie den vollständigen aufschlussreichen Artikel hier.

Wenn es also um GCC-Konstante-Funktionen geht, sprechen wir von Optimierungen und nicht von Funktionsveränderlichkeit.

2
Pavan Manjunath

1. Syntax kann nirgendwo Platz nehmen, um 'const' zu setzen, um die Inhalte einer Funktion konstant zu machen.

Sie werden auf 'Funktion ist kein l-Wert' stoßen, egal ob Sie const haben oder nicht.

typedef void (* FUNC)(void);
FUNC pFunc;
pFunc = 0;     // OK
*pFunc = 0;    // error:  Cannot assign to a function (a function is not an l-value)

typedef void (* const FUNC)(void);
FUNC pFunc;
pFunc = 0;     // error  (const)
*pFunc = 0;    // error:  Cannot assign to a function (a function is not an l-value)

typedef void (const * FUNC)(void);   // error:  <cv-qualifier>  (lol?)

2 & 3. Funktionszeiger- ja .. Funktionsinhalte, sieht nicht aus.

4. Ich glaube nicht, dass es einen Weg gibt, einen Funktionszeiger sicherer zu machen. Bei allen Konstanten der Welt können Sie nur schützen, dass 'SetCallback' seine eigene lokale Kopie des Parameters nicht ändern kann.

typedef void (* const FUNC)(void);
void SetCallback(const FUNC const pCallback)
{
  FUNC pTemp = pCallback;   // OK  (even though pTemp is not const!!)
  pCallback = 0;            // error  (const)
}
0
druid

1.Was bedeutet ein Zeiger auf eine konstante Funktion gegenüber einem Zeiger auf eine nicht konstante Funktion?

Es gibt keinen Unterschied zwischen const und non-const: Die Funktion selbst ist nicht änderbar

Anmerkung: Wenn in C++ die Funktion eine Member-Funktion einer Klasse ist, bedeutet const, dass der Status des Objekts innerhalb dieser Funktion nicht geändert werden kann (Member-Variablen, die aufgerufen werden und nicht-const-Member-Funktionen aufgerufen werden). In diesem Fall ist das Schlüsselwort const Teil der Signatur der Mitgliedsfunktion und unterscheidet sich daher hinsichtlich des Zeigers.

2.Kann eine Funktion const sein?

Siehe oben.

3.Kann eine Funktion nicht konstant sein (veränderlich)?

Siehe oben

4.Was ist die richtige (sichere) Syntax für das Übergeben eines Funktionszeigers?

Alle Zeiger auf freie Funktionen können in einen anderen Zeiger auf freie Funktion umgewandelt werden (d. H. Ihre Größe ist gleich). Sie können also einen Typ für eine (hypothetische) Funktion definieren: void f(); und alle Funktionszeiger in diesen Typ zum Speichern konvertieren. Hinweis dass Sie die Funktion nicht über diesen allgemeinen Typ aufrufen sollten: Sie müssen sie in ihren ursprünglichen Zeiger-zu-Funktionstyp umwandeln, andernfalls erhalten Sie undefiniertes Verhalten (und höchstwahrscheinlich einen Absturz).

Für C++: Es ist nicht garantiert, dass Zeiger auf Member-Funktionen in Zeiger auf freie Funktionen konvertiert werden können

0
Attila