__attribute__((const)) vs. __attribute__((pure)) in GNU C

Lesezeit: 4 Minuten

Was ist der Unterschied zwischen __attribute__((const)) und __attribute__((pure)) in GNU-C?

__attribute__((const)) int f() {
    /* ... */
    return 4;
}

vs

__attribute__((pure)) int f() {
    /* ... */
    return 4;
}

Benutzeravatar von Paul R
Paul R

Von dem Dokumentation für den ARM-Compiler (basiert auf gcc):

__attribute__((pure)) Funktionsattribut
Viele Funktionen haben keine Wirkung, außer einen Wert zurückzugeben, und ihr Rückgabewert hängt nur von den Parametern und globalen Variablen ab. Funktionen dieser Art können einer Datenflussanalyse unterzogen und gegebenenfalls eliminiert werden.

__attribute__((const)) Funktionsattribut
Viele Funktionen untersuchen nur die an sie übergebenen Argumente und haben außer dem Rückgabewert keine Auswirkungen. Dies ist eine viel strengere Klasse als __attribute__((pure)), da eine Funktion den globalen Speicher nicht lesen darf. Wenn bekannt ist, dass eine Funktion nur mit ihren Argumenten arbeitet, dann kann sie einer gemeinsamen Unterausdruckseliminierung und Schleifenoptimierung unterzogen werden.

Also, TL;DR: __attribute__((const)) ist das gleiche wie __attribute__((pure)) aber ohne Zugriff auf globale Variablen.

  • Beachten Sie, dass der ARM-Compiler auch eine __pure Funktionsqualifizierer, der strenger ist als der pure Attribut und entspricht dem const Attribut.

    – jap

    31. Januar 2017 um 8:40 Uhr

  • Erwähnenswert ist auch der Hinweis zu Zeigerargumenten in der GCC-Dokumentation: Note that a function that has pointer arguments and examines the data pointed to must not be declared const

    – Ursprung

    7. März 2017 um 16:44 Uhr

  • @origo IMO const wäre in Ordnung, wenn der Zeiger auf schreibgeschützte Daten zeigt, z. B. wenn es sich um ein Zeichenfolgenliteral handelt.

    – rockdaboot

    8. Mai 2019 um 12:43 Uhr

Antti Haapala -- Benutzeravatar von Слава Україні
Antti Haapala – Слава Україні

Der Unterschied wird in der erklärt GCC-Handbücher. Vor allem a const Die Funktion darf nur die übergebenen Argumente und keinen Speicher verwenden, während a pure Die Funktion kann unter Einschränkungen auch auf den Speicher zugreifen:

Das Attribut pure verbietet einer Funktion, den beobachtbaren Zustand des Programms auf andere Weise als durch die Untersuchung des Rückgabewerts der Funktion zu ändern. Mit dem Attribut pure deklarierte Funktionen können jedoch alle nichtflüchtigen Objekte sicher lesen und den Wert von Objekten so ändern, dass der Rückgabewert oder der beobachtbare Zustand des Programms nicht beeinflusst werden.

Das __attribute__ ((pure)) bedeutet, dass die Funktion keine Seiteneffekte hat und der zurückgegebene Wert von den Argumenten und dem Zustand der globalen Variablen abhängt. Daher ist es für den Optimierer sicher, einige Aufrufe zu eliminieren, wenn die Argumente gleich sind, und die Der Anrufer hat zwischen den Anrufen nichts getan, um den Status der Globals zu ändern.

Das __attribute__ ((const)) bedeutet, dass der Rückgabewert ausschließlich eine Funktion der Argumente ist, und wenn eines der Argumente Zeiger sind, dann die Zeiger darf nicht dereferenziert werden.

EIN const Funktion ist immer pure.

Beispiele von const Funktionen wären das abs Funktionen ab <stdlib.h> und einige mathematische Funktionen aus <math.h>: sqrt, expusw. (obwohl sie Rundungsmodi unterliegen können).

Beispiele von pure aber nicht konstante Funktionen wären solche Funktionen wie strlen – da es den übergebenen Zeiger dereferenziert.

  • Gemessen an dem, was der Optimierer tut, greift eine reine Funktion möglicherweise nicht auf globale Variablen zu, deren Zustand durch Faktoren geändert werden kann, die außerhalb des Kontrollflusses liegen, in dem die reine Funktion erscheint. Also globale Variablen, die einem Gerätezustand zugeordnet sind, oder solche, die von einem anderen Thread geändert werden könnten, und so weiter.

    – Allmächtig

    22. Februar 2019 um 3:01 Uhr

  • Ja, der Unterschied zwischen den 2 besteht eher darin, dass eine reine Funktion ihren Rückgabewert ändern kann, wenn der Aufrufer eine globale Änderung vorgenommen hat

    – Antti Haapala – Слава Україні

    22. Februar 2019 um 4:44 Uhr

  • Schließlich ist das Attribut ein Signal für den Aufrufer, und der Aufrufer kann nicht den Zustand aller existierenden Memory-Mapped-Variablen kennen 😀

    – Antti Haapala – Слава Україні

    22. Februar 2019 um 4:49 Uhr

  • Neue Formulierung: “und Anrufer hat zwischen den Anrufen nichts getan, um den Status der Globals zu ändern.”

    – Antti Haapala – Слава Україні

    22. Februar 2019 um 4:50 Uhr

  • Argh link b0rken. @Omnifarious Anscheinend hat es sich kürzlich geändert und ist viel besser als zu der Zeit, als ich die Antwort geschrieben habe. Dies ist die von der Zeit, als ich die Frage beantwortete

    – Antti Haapala – Слава Україні

    22. Februar 2019 um 5:23 Uhr

Beachten Sie, dass, wenn einer Funktion ein Zeiger übergeben wird und der Kontext dieses Zeigers untersucht wird, sie nicht deklariert werden kann constauch wenn der übergebene Zeiger und der Zeiger Kontexte sind const. Dies ist eine starke Einschränkung der Nützlichkeit von const.

Sie können mehrere Werte in C zurückgeben, indem Sie eine Struktur verwenden, was die Verwendung vereinfacht pure. (Es ist üblicher, Zeigerrückgabeoperanden zu verwenden, aber dies unterbricht die Verwendung von pure).

1408360cookie-check__attribute__((const)) vs. __attribute__((pure)) in GNU C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy