Hallo, ich sehe gerade bei einer static void Function in C das attribute "noreturn".
1 | static void function(uint8_t x, uint8_t y) __attribute__((noreturn)); |
aber wofür das attribute? void gibt doch eh nichts zurück?
|
Forum: PC-Programmierung attribute noreturnHallo, ich sehe gerade bei einer static void Function in C das attribute "noreturn".
aber wofür das attribute? void gibt doch eh nichts zurück? noreturn hat nichts mit dem Rueckgabewert zu tun, sondern sagt dem Compiler, das die Funktion nie verlassen wird. Dadurch kann der Compiler anders optimieren. https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
Denn Sinn dahinter habe ich allerdings nie verstanden (außer bei main()). Wenn die Funktion niemals beendet wird - warum sollte ich sie beschleunigen wollen? Walter T. schrieb: > Denn Sinn dahinter habe ich allerdings nie verstanden (außer bei > main()). Wenn die Funktion niemals beendet wird - warum sollte ich sie > beschleunigen wollen? Kaj schrieb: > More importantly, it helps avoid spurious warnings of uninitialized > variables. Das ist denke ich eher der Punkt. Jens schrieb: > static void function(uint8_t x, uint8_t y) __attribute__((noreturn)); Eine Funktion, der man Argumente übergibt und die nur einmal aufgerufen werden kann, macht wenig Sinn. Vermutlich ist sie in Assembler geschrieben, d.h. das RET steht als Instruktion am Ende. Besser schreibt man daher: __attribute__((naked)) Sven B. schrieb: > Walter T. schrieb: >> Denn Sinn dahinter habe ich allerdings nie verstanden (außer bei >> main()). Wenn die Funktion niemals beendet wird - warum sollte ich sie >> beschleunigen wollen? > > Kaj schrieb: >> More importantly, it helps avoid spurious warnings of uninitialized >> variables. > > Das ist denke ich eher der Punkt. Magst Du dazu vielleicht eine Erklärung geben? Ein Beispiel? Einen Link? In welcher Konstellation kann es fälschlicherweise eine Warnung vor uninitialisierten Variablen geben?
oder sowas in die Richtung? Peter D. schrieb: > Eine Funktion, der man Argumente übergibt und die nur einmal aufgerufen > werden kann, macht wenig Sinn. Das macht sogar sehr viel Sinn. Beispiel: Ein Thread der von der von einer Schnittstelle liest.
Warum macht es keinen Sinn der Funktion Argumente zu geben? Und warum sollte ich die Funktion mehrfach aufrufen koennen? (Was ja trotzdem geht, naemlich als Thread) Peter D. schrieb: > Vermutlich ist sie in Assembler geschrieben, d.h. das RET steht als > Instruktion am Ende. > Besser schreibt man daher: __attribute__((naked)) Unsinn. Voellig verschiedene Paar Schuhe. Walter T. schrieb: > Wenn die Funktion niemals beendet wird - warum sollte ich sie > beschleunigen wollen? Wenn die Funktion nicht beendet wird, brauchst du die Ruecksprungadresse nicht speichern. Kaj schrieb: > Das macht sogar sehr viel Sinn. Man kann natürlich viel spekulieren. Für mich klingt das nach Position setzen (x,y), d.h. sie wird sehr wohl mehrfach aufgerufen und muß daher auch zurück kehren. Grafikfunktionen in Assembler sind durchaus gebräuchlich, um sie schneller zu machen. Kaj schrieb: > Wenn die Funktion nicht beendet wird, brauchst du die Ruecksprungadresse > nicht speichern. Das wäre dann ein Jump. Funktionsaufrufe sind aber immer Calls, d.h. die CPU sichert immer den PC. Also, es gibt erstmal diese Attribut. Schön. Der Sinn erschliesst sich mir aber auch nicht so recht. Das Folgende nur der Diskussion halber. Wer die Verwendung für angebracht hält mag es verwenden. Es liegt vielleicht an meiner mangelnder Phantasie. Bzw. umgekehrt daran, dass ich für die zwei (im den Dokumentationen genanten Fälle) bisher genug Phantasie :-) hatte und alternative Forumulierungen benutze, die dieses Attribut von vorne herein unnötig machen. 1. Vermeidung von Tail-Calls: Falls Funktionen nicht zurückkehren (wie etwa exit()), dann schreibe ich den Code so, dass danach nicht etwa noch andere Anweisungen stehen. D.h. eine evtl. Umstellung von Anweisungen, so dass eine nicht-zurückkehrende Funktion nach diesen Anweisungen ausgeführt werden könnte, und also deren Seiteneffekte unbeabsichtigt wirksam werden, gibt es in meinem Code garnicht. 2. Vermeidung von Überflüssigen Warnungen vor uninitialisierten Variablen: Ich verwende Variablen (Deklarationen und als Teilausdrücke) überhaupt nur in den Verzeigungen, in denen der Programmablauf garantiert zu diesen Anweisungen führt. Als Beispiel wandle ich den Code von Sven ab. (Sorry, Sven. Ich bin Dir dankbar, dass Du überhaupt geantwortet hast. Nichts für ungut).
Wäre interessant mal produktiven Code (etwa aus einem Open-Source-Projekt) zu sehen, der das Attribut verwendet. Man muss hier Mikrocontroller und Rechner mit "richtigem" Betriebssystem unterscheiden. Bei letzteren macht main() durchaus ein return und liefert einen Status. Der wird vom Betriebssystem an den Aufrufer (z.B. eine shell) des Programms weitergegeben. Wenn der Benutzer das Programm mit falschen Parametern aufruft, kann es kaum mehr als eine Fehlermeldung ausgeben und abbrechen. Das geht z.B. mit exit(EXIT_FAILURE) und bei der Funktion ist das Attribut ja wohl angebracht. Das printf() für die Meldung und das exit() werden gerne zusammen in eine eigene Funktion wie die fatal() von Sven verpackt. Die macht dann auch kein return und bekommt logischerweise auch dieses Attribut. Bei uC mit Multitasking gilt das genauso, nur bei einfachen uC-Programmen gibt es wenig Anwendungen. Eine Funktion könnte in einer Endlosschleife auf einen Watchdog-Reset warten. Einfache Fault-Handler verdienen sicher auch das Attribut. Meine crt0 hat ein _attribute_ ((naked, noreturn)). Das finde ich total angemessen, wohin sollte die zurückkehren? Theor schrieb: > Wäre interessant mal produktiven Code (etwa aus einem > Open-Source-Projekt) zu sehen, der das Attribut verwendet. Der Linux Kernel setzt das, an verschiedenen Stellen ein. meist hinter dem define __noreturn. imonbln schrieb: > Theor schrieb: >> Wäre interessant mal produktiven Code (etwa aus einem >> Open-Source-Projekt) zu sehen, der das Attribut verwendet. > > Der Linux Kernel setzt das, an verschiedenen Stellen ein. meist hinter > dem define __noreturn. Ah. Guck mal an. Danke. Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
|
|