Können wir Kommentare in Variablennamen schreiben?

Lesezeit: 4 Minuten

Benutzeravatar von Vinita
Vinita

int main()
{
     i/*nt*/a = 10;
     return 0;
}

Wenn ich den obigen Code habe und die Token zählen möchte, werden es 14 oder 13 Token sein?

Ist es gültig, einen Kommentar in einen Variablennamen zu schreiben? Sie können davon ausgehen, dass die int i, int a, int ia sind global definiert.

  • In “traditionellem” C vor ANSI, zumindest wie von implementiert GNU cpp -traditionalwürde es erweitern ia = 10;.

    – Nate Eldredge

    27. August 2020 um 4:42 Uhr


  • Was für eine interessante Frage – warum ist sie mir noch nie in den Sinn gekommen?

    – WestCoastProjects

    27. August 2020 um 15:47 Uhr

  • @javadba: Weil vernünftige Leute nicht auf die Idee kommen, so etwas zu tun?

    – jamesqf

    27. August 2020 um 16:23 Uhr


  • Wenn Sie das wirklich wollen, können Sie zu Fortran wechseln. Leerzeichen außerhalb von Zeichenfolgen werden in der ersten Analysestufe entfernt.

    – mpez0

    27. August 2020 um 16:49 Uhr

  • Ich wollte gerade den Titel ändern in “…. innerhalb Variablennamen …”, aber dann wurde mir klar, dass Sie möglicherweise tatsächlich “zwischen” gemeint haben. (Ich wollte es bearbeiten, weil die Antwort auf den ursprünglichen Titel “Warum, offensichtlich!” lautet. Der wichtige Teil ist “kein Leerzeichen”.) Würde Der Titel “Trennt ein Kommentar (ohne umgebendes Leerzeichen) Tokens in C?” drückt Ihre eigentliche Frage aus?

    – Peter – Setzen Sie Monica wieder ein

    28. August 2020 um 7:25 Uhr


Benutzeravatar von chqrlie
chqrlie

Die Kommentare werden während Phase 3 der Programmübersetzung entfernt1: Jeder Kommentar wird durch ein Leerzeichen ersetzt. also der kommentar /*nt*/ ist definitiv kein Token.

Wenn keine von int, main, i, a oder return sind als Vorverarbeitungsmakros definiert, die das Parsen des Programms erzeugt 14 Token (nicht 13):

int main ( ) { i a = 10 ; return 0 ; }

Wenn nicht i ist als Typ mit a definiert typedef Anweisung, gibt es einen Syntaxfehler als i a stimmt nicht mit einer Regel in der C-Grammatik überein.

Sie können also keine Kommentare schreiben Innerhalb Variablennamen teilt der Kommentar den Bezeichner in 2 separate Tokens. Dies gilt für alle Vorverarbeitungs- und C-Sprachtoken2.

Beachten Sie jedoch, dass Sie an ungewöhnlichen Stellen Kommentare einfügen können, z. B. zwischen unären Operatoren und ihrem Operanden oder zwischen den # und die Vorverarbeitungsanweisung und ihre Argumente:

/**/#/**/include/**/<stdio.h>/**///////////////////////
/**/#/**/define/**/STAT/**/(/**/a/**/)/**/-/**/1/**////
/**/#/**/ifdef/**/STAT/**//////////////////////////////
/**/int/**/main/**/(/**/)/**/{/**//////////////////////
/**/int/**/a/**/=/**/+/**/1/**/;/**////////////////////
/**/printf/**/(/**/"Hello "/**/"world!\n"/**/)/**/;/**/
/**/return/**/STAT/**/;/**/////////////////////////////
/**/}/**///////////////////////////////////////////////
/**/#/**/endif/**//////////////////////////////////////

Aber die obige Makrodefinition definiert kein funktionsähnliches Makro, sondern ein reguläres Makro STAT das erweitert sich zu ( a ) - 1.

Variablennamen können wie jedes andere Token durch Zeilenumbrüche mit Escapezeichen geteilt werden. Escapezeichen für Zeilenumbrüche sind Sequenzen oder \ unmittelbar gefolgt von einem Zeilenumbruch. Diese Sequenzen werden während Phase 2 der Programmübersetzung aus dem Quellcode entfernt. Ihr Hauptzweck besteht darin, lange Makrodefinitionen in mehreren Zeilen zu unterbrechen.

Unten ist ein Codefragment3 das erzeugt die gleichen 14 Token:

\
i\
nt\
 ma\
in()
{\
i/\
*nt\
*/a \
= 10;
r\
et\
urn\
 0;}

Beachten Sie, wie der Code Colorizer die geschnittenen und gewürfelten Schlüsselwörter und Kommentare verpasst hat 🙂


1) Dieses Verhalten wurde in ANSI-C alias C89 spezifiziert. Einige alte Compiler hatten ein subtil anderes Verhalten, was zum Einfügen von Token führte, aber solche Besonderheiten sind nur von historischem Interesse.

2) Sie können fast einen Kommentar in eine String-Konstante einfügen, indem Sie sich die Tatsache zunutze machen, dass benachbarte String-Konstanten in Phase 6 der Programmübersetzung verkettet werden: printf("Hello "/* my name is Luca */"world!\n");

3) Dies Weihnachtsbaum Der Präsentationsstil ist nicht dazu gedacht, in echten Programmen verwendet zu werden, er zeigt, wie die Eingabeverarbeitungsfähigkeiten von C missbraucht werden können. Ausgefeiltere Tricks haben gewonnen Der internationale Wettbewerb für verschleierten C-Code

Benutzeravatar von dbush
dbusch

Aus lexikalischer Sicht ist ein Kommentar dasselbe wie ein Leerzeichen.

Abschnitt 6.4p3 des C-Standard zu lexikalischen Elementen heißt es:

… Vorverarbeitungstoken können durch getrennt werden weißer Raum; diese besteht aus Kommentaren (später beschrieben) oder Leerzeichen (Leerzeichen, horizontaler Tabulator, neue Zeile, vertikaler Tabulator und Seitenvorschub) oder beides. …

Genauer gesagt wird ein Kommentar in ein einzelnes Leerzeichen übersetzt. Dies ist in Abschnitt 5.1.1.2p3 spezifiziert:

Die Quelldatei wird in Vorverarbeitungstoken und Sequenzen von Leerzeichen (einschließlich Kommentaren) zerlegt. Eine Quelldatei darf nicht mit einem teilweisen Vorverarbeitungstoken oder einem teilweisen Kommentar enden. Jeder Kommentar wird durch ein Leerzeichen ersetzt.
Zeilenumbrüche bleiben erhalten. Ob jede nicht leere Folge von Leerzeichen außer New-Line beibehalten oder durch ein Leerzeichen ersetzt wird, ist implementierungsdefiniert.

Um dies zu veranschaulichen, wenn Sie Ihren Code durch den Präprozessor leiten, erhalten Sie Folgendes:

  int main()
  {
       i a = 10;
       return 0;

  }

Kommentare dienen also wie Leerzeichen dazu, Token zu trennen.

Das bedeutet, dass der Code 14 Token enthält, nicht 13.

Das Ergebnis wird so sein, als ob Sie geschrieben hätten:

i a = 10;

NICHT:

ia = 10;

Benutzeravatar von JaMiT
JaMiT

Siehe Übersetzung (auch bekannt als Kompilieren) Phase 3Schritt 2: “Jeder Kommentar wird durch ein Leerzeichen ersetzt”.

Also konzeptionell i/*nt*/a wird i a an diesem Punkt.

Überprüfen Sie einfach, welche Form Ihr Stück Code hat

     int main()
    {
        int i/*nt*/a = 10;
        return 0;
    }

wird nach der Vorverarbeitung haben. Fügen Sie Ihrem Compiler einfach das Flag “-E” hinzu, gcc -E myscript.c und Sie erhalten das Ergebnis:

e.sharaborin@landau:~$ gcc -E myscript.c
# 1 "myscript.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "myscript.c"
int main()
{
    int i a = 10;
    return 0;
}

Und natürlich können Sie daraus schließen, dass ein Fehler vorliegt.

1424080cookie-checkKönnen wir Kommentare in Variablennamen schreiben?

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

Privacy policy