C-Attribut: unsequenced, reproducible (seit C23)
Gibt dem Compiler Informationen über den Zugriff auf Objekte durch eine Funktion, so dass bestimmte Eigenschaften von Funktionsaufrufen abgeleitet werden können.
Inhalt |
[bearbeiten] Syntax
[[ unsequenced ]][[ __unsequenced__ ]] |
(1) | ||||||||
[[ reproducible ]][[ __reproducible__ ]] |
(2) | ||||||||
[bearbeiten] Erklärung
Diese Attribute werden auf einen Funktionsdeklarator oder einen Typspezifizierer angewendet, der einen Funktionstyp hat. Das entsprechende Attribut ist eine Eigenschaft des Funktionstyps.
[bearbeiten] Effektlos
Eine Auswertung eines Funktionsaufrufs ist effektlos, wenn jede während des Aufrufs sequenzierte Speicheroperation die Modifikation eines Objekts ist, das mit dem Aufruf synchronisiert ist; wenn die Operation zusätzlich beobachtbar ist, müssen alle Zugriffe auf das Objekt auf einem eindeutigen Zeigerparameter der Funktion basieren.
[bearbeiten] Idempotent
Eine Auswertung E ist idempotent, wenn eine zweite Auswertung von E unmittelbar nach der ursprünglichen sequenziert werden kann, ohne den resultierenden Wert, falls vorhanden, oder den beobachtbaren Zustand der Ausführung zu ändern.
[bearbeiten] Zustandslos
Eine Funktion F ist zustandslos, wenn jede Definition eines Objekts mit statischer oder Thread- Speicherdauer in F oder in einer von F aufgerufenen Funktion const, aber nicht volatile-qualifiziert ist.
[bearbeiten] Unabhängig
Eine Funktion F ist unabhängig, wenn für jedes Objekt X, das durch einen Aufruf von F über einen L-Wert beobachtet wird, der nicht auf einem Parameter des Aufrufs basiert, alle Zugriffe auf X in allen Aufrufen von F während derselben Programmausführung denselben Wert beobachten; andernfalls, wenn der Zugriff auf einem Zeigerparameter basiert, muss es einen eindeutigen solchen Zeigerparameter P geben, so dass jeder Zugriff auf X auf einen L-Wert erfolgen muss, der auf P basiert.
Ein Objekt X wird durch einen Funktionsaufruf beobachtet, wenn beide synchronisieren, wenn X nicht lokal für den Aufruf ist, wenn X eine Lebensdauer hat, die vor dem Funktionsaufruf beginnt, und wenn ein Zugriff auf X während des Aufrufs sequenziert wird; der letzte Wert von X, falls vorhanden, der vor dem Aufruf gespeichert wurde, wird als der Wert von X bezeichnet, der durch den Aufruf beobachtet wird.
[bearbeiten] Hinweise
Diese Attribute existieren zum Zweck der Compiler-Optimierung.
Wenn eine Funktion reproduzierbar ist, können mehrere nachfolgende Aufrufe als ein einzelner Aufruf behandelt werden.
Wenn eine Funktion nicht sequenziert ist, können mehrere nachfolgende Aufrufe als ein einzelner Aufruf behandelt werden, und die Aufrufe können parallelisiert und beliebig neu geordnet werden.