__func__ außerhalb der Funktionsdefinition

Lesezeit: 3 Minuten

Benutzer-Avatar
Gefrorenes Herz

Was sollte passieren, wenn wir eine vordefinierte Variable verwenden __func__ außerhalb einer Funktion in C (C99 / C11) und C++?

#include <stdio.h>

const char* str = __func__;

int main(void)
{
   printf("%s", str);
   return 0;
}

gcc 4.7.2 gibt nur eine Warnung aus (mit -Wall -W -pedantic aktiviert) und druckt nichts.

Standard sagt dazu explizit nichts:

ISO/IEC 14882:2011

8.4.1 Allgemein [dcl.fct.def.general]

8 Die funktionslokale vordefinierte Variable __func__ ist definiert als ob eine Definition des Formulars static const char __func__[] = "function-name";
bereitgestellt wurde, wobei Funktionsname eine implementierungsdefinierte Zeichenfolge ist. Es ist nicht angegeben, ob eine solche Variable eine Adresse hat, die sich von der eines anderen Objekts im Programm unterscheidet.

ISO/IEC 9899:2011

6.4.2.2 Vordefinierte Identifikatoren

1 Die Kennung __func__ muss vom Übersetzer implizit so deklariert werden, als ob unmittelbar nach der öffnenden geschweiften Klammer jeder Funktionsdefinition die Deklaration static const char __func__[] = "function-name";
erschien, wobei Funktionsname der Name der lexikalisch einschließenden Funktion ist.

UB? Fehler? Oder etwas anderes?

  • Ich stimme für einen Fehler angesichts der Formulierung “funktionslokale vordefinierte Variable” und “unmittelbar nach der öffnenden geschweiften Klammer jeder Funktionsdefinition” in Ihren Zitaten.

    – jpalecek

    2. Januar 2013 um 13:58 Uhr

  • Jedes Verhalten, das nicht durch den Standard definiert ist, ist durch Eliminierung ein undefiniertes Verhalten 😉

    – Oliver Charlesworth

    2. Januar 2013 um 13:58 Uhr

Der Standard sagt dazu explizit nichts

Dies bedeutet undefiniertes Verhalten.

Aus dem C-Standard (Hervorhebung von mir):

(C99, 4.p2) „Wenn eine ‚soll‘- oder ‚darf nicht‘-Anforderung verletzt wird, die außerhalb einer Beschränkung erscheint, ist das Verhalten undefiniert. Nicht definiertes Verhalten wird in dieser Internationalen Norm ansonsten durch die Worte ‚ „undefiniertes Verhalten“ oder durch das Weglassen einer expliziten Verhaltensdefinition. Zwischen diesen dreien gibt es keinen Unterschied in der Betonung; sie alle beschreiben ”undefiniertes Verhalten”.”

(Aufgestuft von einem früheren Kommentar)

__func__ befindet sich im reservierten Namensraum, so dass die Implementierung es für beliebige Zwecke im Bereich des Namensraums verwenden darf, dh die Implementierung muss keine (Miss-)Verwendung von diagnostizieren __func__ außerhalb einer Funktion, da nichts im Standard die Definition einer Implementierung verbietet __func__ als Namespace-Scope-Array von char wenn es das ist, was die Implementierer tun wollen.

Es könnte undefiniert sein, oder es könnte als String oder irgendetwas anderes definiert sein, und diese Implementierung ist immer noch konform.

Es ist also ein undefiniertes Verhalten, es außerhalb einer Funktion zu verwenden, da es definiert sein kann oder nicht und vom richtigen Typ sein kann, um verwendbar zu sein oder nicht.

Für konkrete Beispiele, wie der Code in der Frage ein undefiniertes Verhalten haben könnte, wenn er mit einer konformen Implementierung verwendet wird, glaube ich, dass eine Implementierung ihn definieren könnte nullptr (also würde das Beispiel abstürzen printf) oder könnte es sogar zu einem Makro definieren, das zu einer Dereferenzierung eines Nullzeigers und dann erweitert wird #undef es beim Eintritt in jede Funktion und #define es nach jeder Funktion (das Beispiel würde also vorher abstürzen main beginnt!)

  • +1 für eine gründliche Erklärung anstelle nur eines pedantischen Zitats.

    – larmbr

    3. Januar 2013 um 5:34 Uhr

1299360cookie-check__func__ außerhalb der Funktionsdefinition

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

Privacy policy