Warum wird dieses Programm von drei C ++ - Compilern fälschlicherweise abgelehnt?


468

Ich habe einige Schwierigkeiten beim Kompilieren eines von mir geschriebenen C ++ - Programms.

Dieses Programm ist sehr einfach und entspricht nach meinem besten Wissen allen im C ++ Standard festgelegten Regeln. Ich habe die gesamte ISO / IEC 14882: 2003 zweimal durchgelesen, um sicherzugehen.

Das Programm ist wie folgt:

Geben Sie hier die Bildbeschreibung ein

Hier ist die Ausgabe, die ich beim Versuch erhalten habe, dieses Programm mit Visual C ++ 2010 zu kompilieren:

c:\dev>cl /nologo helloworld.png
cl : Command line warning D9024 : unrecognized source file type 'helloworld.png', object file assumed
helloworld.png : fatal error LNK1107: invalid or corrupt file: cannot read at 0x5172

Bestürzt habe ich g ++ 4.5.2 ausprobiert, aber es war ebenso wenig hilfreich:

c:\dev>g++ helloworld.png
helloworld.png: file not recognized: File format not recognized
collect2: ld returned 1 exit status

Ich dachte mir, dass Clang (Version 3.0 Kofferraum 127530) funktionieren muss, da es für seine Standardkonformität so hoch gelobt wird. Leider hat es mir nicht einmal eine seiner hübschen, hervorgehobenen Fehlermeldungen gegeben:

c:\dev>clang++ helloworld.png
helloworld.png: file not recognized: File format not recognized
collect2: ld returned 1 exit status
clang++: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)

Um ehrlich zu sein, weiß ich nicht wirklich, was diese Fehlermeldungen bedeuten.

Viele andere C ++ - Programme haben Quelldateien mit der Erweiterung .cpp , daher dachte ich, ich müsste meine Datei möglicherweise umbenennen. Ich habe den Namen in helloworld.cpp geändert , aber das hat nicht geholfen. Ich denke, es gibt einen sehr schwerwiegenden Fehler in Clang, denn als ich versuchte, das umbenannte Programm damit zu kompilieren, flippte es aus und druckte "84 Warnungen und 20 generierte Fehler". und mein Computer piepste viel!

Was habe ich hier falsch gemacht? Habe ich einen kritischen Teil des C ++ - Standards verpasst? Oder sind alle drei Compiler wirklich so kaputt, dass sie dieses einfache Programm nicht kompilieren können?

Antworten:


173

In der Norm legt §2.1 / 1 fest:

Die Zeichen der physischen Quelldatei werden bei Bedarf implementierungsdefiniert dem grundlegenden Quellzeichensatz zugeordnet (Einführung neuer Zeilenzeichen für Zeilenende-Indikatoren).

Ihr Compiler unterstützt dieses Format nicht (auch bekannt als kann es nicht dem grundlegenden Quellzeichensatz zugeordnet werden ), sodass er nicht in weitere Verarbeitungsstufen übergehen kann, daher der Fehler. Es ist durchaus möglich, dass Ihr Compiler eine Zuordnung vom Bild zum grundlegenden Quellzeichensatz unterstützt, dies ist jedoch nicht erforderlich.

Da diese Zuordnung implementierungsdefiniert ist, müssen Sie in der Implementierungsdokumentation nachsehen, welche Dateiformate unterstützt werden. Normalerweise unterstützt jeder große Compilerhersteller (kanonisch definierte) Textdateien: jede Datei, die von einem Texteditor erstellt wird, normalerweise eine Reihe von Zeichen.


Beachten Sie, dass der C ++ - Standard auf dem C-Standard (§1.1 / 2) basiert und der C (99) -Standard in §1.2 besagt:

Diese Internationale Norm legt nicht fest,
durch welchen Mechanismus C-Programme zur Verwendung durch ein Datenverarbeitungssystem transformiert werden.
- den Mechanismus, mit dem C-Programme zur Verwendung durch ein Datenverarbeitungssystem aufgerufen werden;
- den Mechanismus, mit dem Eingabedaten zur Verwendung durch ein C-Programm transformiert werden;

Die Behandlung von Quelldateien ist also wieder etwas, das Sie in Ihrer Compiler-Dokumentation finden müssen.


23
Ich denke, dieser Satz ist bestenfalls mehrdeutig. Der Merriam-Webster - Wörterbuch sagt , dass Text ist die ursprünglichen Worte und Form einer schriftlichen oder gedruckten Arbeit oder eine Arbeit mit solchen Text . Diese Quelldatei fällt eindeutig unter diese Definition. Denken Sie, ich sollte einen Fehlerbericht bei der Kernsprachen-Arbeitsgruppe einreichen?
James McNellis

15
Oh; Ich habe völlig vergessen, alle Dokumente zu lesen, auf die verwiesen wird. Ich denke jedoch, dass dieser Absatz aus dem Zusammenhang gerissen ist, daher werde ich die gesamte ISO / IEC 9899: 1990 lesen und hier posten, sobald ich ihn vollständig verstanden habe.
James McNellis



211

Ihr <und >, (und ), {und }scheinen nicht sehr gut zusammen zu passen; Versuche sie besser zu zeichnen.


44
Obwohl ich es nicht schätze, dass Sie sich über meine Handschrift lustig machen, könnte dies das eigentliche Problem sein und den Fehler erklären, den ich beim Kompilieren der umbenannten helloworld.cpp mit Visual C ++ erhalte: "Schwerwiegender Fehler C1004: unerwartetes Ende von- Datei gefunden "Ich werde es erneut versuchen und mich bald melden. Vielen Dank!
James McNellis

37
@ James stellt sicher, dass Sie alle PNG-Optimierungen deaktivieren. Dies erleichtert das Debuggen.
Wilhelmtell

5
@ James: "Unerwartetes Dateiende" bedeutet mit ziemlicher Sicherheit, dass es Ihr }Problem ist. Versuchen Sie, sich darauf zu konzentrieren, das mit dem{
Carson63000

156

Sie können das folgende Python-Skript ausprobieren. Beachten Sie, dass Sie PIL und Pytesser installieren müssen .

from pytesser import *
image = Image.open('helloworld.png')  # Open image object using PIL
print image_to_string(image)     # Run tesseract.exe on image

Um es zu verwenden, gehen Sie wie folgt vor:

python script.py > helloworld.cpp; g++ helloworld.cpp

110

Sie haben vergessen, Comic Sans als Schriftart zu verwenden, deshalb ist es fehlerhaft.


73
Leider ist dies die einzige Schriftart, die meine Hand unterstützt. Das wäre sehr traurig, wenn ich aus diesem Grund nicht in C ++ programmieren kann. Denken Sie, dass Java diese Schriftart unterstützen würde?
James McNellis

8
Sie benötigen Comic Sans, wenn Sie ohnehin an das Zeichnen von Comics denken. Sie sollten also ernsthaft darüber nachdenken, Ihre Hände zu verbessern.
Scharfzahn

8
C ++ erfordert eine einjährige Ausbildung in Kalligraphie. Wenn Sie keine Zeit haben, versuchen Sie es mit Visual Basic oder einfach nur mit binärem Maschinencode (Sie müssen dann nur die Nullen und Einsen richtig einstellen).
Frank Osterfeld

1
@Frank C ++ 0x §42.1 / 1 gibt an, dass alle Zeichenfolgen in Gothic sein müssen.
Mateen Ulhaq

75

Nach dieser letzten Klammer kann ich keine neue Zeile mehr sehen.

Wie Sie wissen: "Wenn eine nicht leere Quelldatei nicht mit einem Zeilenumbruch endet, ... ist das Verhalten undefiniert."


16
Hmmm. Zum Glück wurde diese lächerliche Regel in C ++ 0x entfernt. Wie beendet man eine solche Datei mit einem Zeilenumbruch? Ich dachte, ich hätte am Ende des Textes genügend Platz gelassen (wenn Sie die Quelldatei markieren, sollten Sie den zusätzlichen Raum sehen, den ich verlassen habe). Danke für den Tipp!
James McNellis

8
Wenn Sie nicht genug Leerzeichen haben, kann ich versuchen, es auf meinem System zu kompilieren. Ich habe vier Monitore, damit ich versuchen kann, von meinem ganz linken zu kompilieren.
der Blechmann

74

Dieses Programm ist gültig - ich kann keine Fehler finden.

Ich vermute, Sie haben einen Virus auf Ihrem Computer. Am besten formatieren Sie Ihr Laufwerk neu und installieren das Betriebssystem neu.

Lassen Sie uns wissen, wie das funktioniert oder ob Sie Hilfe bei der Neuinstallation benötigen.

Ich hasse Viren.


17
Ja, versuchen Sie Linux zu installieren. Ich beschuldige Windows für Ihr Problem.
Raedwald

62

Ich habe festgestellt, dass es hilfreich ist, meinen Code nicht mit einem magischen Marker auf das Glas meines Monitors zu schreiben, obwohl er gut aussieht, wenn er wirklich schwarz ist. Der Bildschirm füllt sich zu schnell und dann rufen mich die Leute, die mir einen sauberen Monitor geben, jede Woche an.

Ein paar meiner Angestellten (ich bin ein Manager) kommen herein, um mir einen dieser Red Pad-Computer mit den Knöpfen zu kaufen. Sie sagten, dass ich keine Marker brauche und den Bildschirm selbst reinigen kann, wenn er voll ist, aber ich muss vorsichtig sein, ihn zu schütteln. Ich nahm an, dass es so empfindlich ist.

Deshalb stelle ich die klugen Leute ein.


2
Ein Wacom Cintiq ist für einen Manager viel besser geeignet. Es ist teuer und gibt Ihnen das Gefühl, wirklich wichtig zu sein. Alle Grafikdesigner in Ihrem Unternehmen haben einen viel niedrigeren Status und sollten daher EGA-Monitore verwenden. Hausmeister sollten CGA-Monitore verwenden. Programmierer sollten gebrauchte monochrome Terminals verwenden.
Steve314

7
Ich hatte lange Zeit einen "Life Like" -Monitor. Es war so realistisch, dass Sie schwören würden, der Bildschirmschoner von schwimmenden Fischen sei echt, und der kleine Taucher sah aus, als würde er schwimmen. Ich machte meinen Arm immer wieder nass und versuchte, die Schatzkiste von unten zu bekommen, es war so real. Das einzige Problem war, dass der Bildschirmschoner immer eingeschaltet war und die realistischen Sprudelgeräusche das Hören erschwerten. Oh, und sie sagten, ich müsse zur Wartung täglich Sachen auf den Monitor streuen, sonst würde der Bildschirmschoner nicht mehr funktionieren. Das hat es einmal getan, und Junge, der Geruch zwei Tage später war wirklich realistisch.
Der Blechmann

59

File format not recognizedSie müssen Ihre Datei richtig formatieren. Das bedeutet, dass Sie die richtigen Farben und Schriftarten für Ihren Code verwenden. Siehe die spezifischen Dokumentationen für jeden Compiler, da diese Farben zwischen den Compilern variieren;)


14
Oh, das macht Sinn ... Ich habe eine Schachtel mit 96 Buntstiften, also bin ich sicher, dass ich die richtige Vordergrundfarbe habe. Ich werde morgen farbiges Konstruktionspapier abholen und es auf einer anderen Papierfarbe ausprobieren.
James McNellis

3
Um sicher zu gehen, sollten Sie auch einige Farbstifte und Ölfarben kaufen. Es ist eine bekannte Tatsache, dass C ++ eine sehr schwer zu formatierende Sprache sein soll.
helloworld922

Ja, und vergessen Sie nicht, den Markierungsmarker zu verwenden.
Scharfzahn

6
@sharptooth - Syntaxhervorhebung ist eine IDE-Funktion - Sie sollten dies nicht von Hand tun. Stellen Sie also sicher, dass Sie einen Roboterarm für diesen Markierungsmarker haben.
Steve314

56

Sie haben den Vorprozessor vergessen. Versuche dies:

pngtopnm helloworld.png | ocrad | g++ -x 'c++' -

8
Oh! Ich dachte, der Präprozessor wäre im Compiler enthalten! Ich werde versuchen, einen Präprozessor zu finden, der auf meinem Windows-Laptop funktioniert.
James McNellis

3
@ James McNellis: Der Präprozessor ist kein Programm, sondern eine Hardware-Sache, die wie eine Hervorhebungsmarkierung aussieht. Sie verschieben sie über Ihren Text und sie wird vorverarbeitet.
Scharfzahn

49

Haben Sie das Programm handgeschrieben und dann in den Computer gescannt? Das ist es, was "helloworld.png" impliziert. In diesem Fall müssen Sie sich darüber im Klaren sein, dass der C ++ - Standard (auch in seiner neuesten Ausgabe) keine optische Zeichenerkennung erfordert und leider in keinem aktuellen Compiler als optionale Funktion enthalten ist.

Möglicherweise möchten Sie die Grafiken in ein Textformat übertragen. Jeder Klartext-Editor kann verwendet werden. Die Verwendung eines Textverarbeitungsprogramms kann zwar einen hübschen Ausdruck erzeugen, führt jedoch höchstwahrscheinlich zu demselben Fehler, den Sie beim Scannen erhalten.

Wenn Sie wirklich abenteuerlustig sind, können Sie versuchen, Ihren Code in ein Textverarbeitungsprogramm zu schreiben. Drucken Sie es aus, vorzugsweise mit einer Schriftart wie OCR-A . Nehmen Sie dann Ihren Ausdruck und scannen Sie ihn wieder ein. Der Scan kann dann über ein OCR-Paket eines Drittanbieters ausgeführt werden, um ein Textformular zu generieren. Das Textformular kann dann unter Verwendung eines von vielen Standard-Compilern kompiliert werden.

Beachten Sie jedoch die hohen Papierkosten, die während der Debugging-Phase anfallen.


Das Henne-Ei-Dilemma: Ist es möglich, C ++ - Code für eine OCR-Software zu schreiben und ohne OCR zu kompilieren?
Jweyrich

5
Nun, duh, du verwendest Assembly für die ursprüngliche OCR.
Kevin Lacquement

@jweyrich - Ich denke, Sie müssen zuerst Ihre C ++ / OCR-Bootstrap mit Ihrer asm / OCR-Toolchain erhalten.
Michael Burr

2
Oh ASM, ja! ASM in Lochkarten .
Jweyrich

46

Zeichnen Sie das folgende Include, um es zu kompilieren:

#include <ChuckNorris>

Ich habe gehört, er kann Syntaxfehler kompilieren ...


46
Ich persönlich bevorzuge #include <JonSkeet>.
Icode4food

40

Leider haben Sie drei Compiler ausgewählt, die alle mehrere Sprachen unterstützen, nicht nur C ++. Sie alle müssen die von Ihnen verwendete Programmiersprache erraten. Wie Sie wahrscheinlich bereits wissen, ist das PNG-Format für alle Programmiersprachen geeignet, nicht nur für C ++.

Normalerweise kann der Compiler die Sprache selbst herausfinden. Wenn das PNG beispielsweise offensichtlich mit Buntstiften gezeichnet ist, weiß der Compiler, dass es Visual Basic enthält. Wenn es so aussieht, als wäre es mit einem Druckbleistift gezeichnet, ist es leicht, den Ingenieur bei der Arbeit zu erkennen, der FORTRAN-Code schreibt.

Dieser zweite Schritt hilft dem Compiler auch in diesem Fall nicht. C und C ++ sehen einfach zu ähnlich aus, bis auf die #include. Daher müssen Sie dem Compiler bei der Entscheidung helfen, welche Sprache es wirklich ist. Jetzt können Sie nicht standardmäßige Mittel verwenden. Beispielsweise akzeptiert der Visual Studio-Compiler / TC und / TP Befehlszeilenargumente , oder Sie können die Option "Kompilieren als: C ++" in der Projektdatei verwenden. GCC und CLang haben ihre eigenen Mechanismen, die ich nicht kenne.

Daher würde ich empfehlen, stattdessen die Standardmethode zu verwenden, um Ihrem Compiler mitzuteilen, dass der folgende Code in C ++ vorliegt. Wie Sie inzwischen festgestellt haben, sind C ++ - Compiler sehr wählerisch, was sie akzeptieren. Daher besteht die Standardmethode zur Identifizierung von C ++ darin, dass die Einschüchterungsprogrammierer ihren C ++ - Code ergänzen. In der folgenden Zeile wird Ihrem Compiler beispielsweise klargestellt, dass es sich um C ++ handelt (und er sollte es besser ohne Beschwerden kompilieren).

// To the compiler: I know where you are installed. No funny games, capice?

10
Ich dachte, wäre #pragmader richtige Weg, um eine Nachricht an den Compiler zu bekommen?
Lev Bishop

33

Probier diese:

Sehen Sie den Dinosaurier im Space Shuttle?


4
Ich denke, es gibt einen Tippfehler - es sollte endl(L) nicht end1(eins) sein. Aber +1 schön gemacht!
Rup

44
Ich habe drei Stunden lang darauf gestarrt, aber ich kann immer noch keinen Dinosaurier oder das Space Shuttle sehen. :-(
oosterwal

32

Ist Ihr Compiler im Expertenmodus?! Wenn ja, sollte es nicht kompiliert werden. Moderne Compiler haben "Hello World!"


27

OCR sagt:

N lml_e <loJ+_e__}

.lnt Mk.,n ( ln+ _rSC Lhc_yh )
h_S_
_l

s_l . co__ <, " H llo uo/_d ! '` << s l . ena_ .
TP__rn _ |
_|

Was verdammt gut ist, um fair zu sein.


4
Wow, die OCR hat sich verbessert, seit ich versucht habe, meine Handschrift zu scannen (habe Stunden damit verbracht, sie auch direkt zu schreiben).
James P.

40
Ich denke, wir müssen ein Perl-Tag hinzufügen.
MSalters

26

helloworld.png: Datei nicht erkannt: Dateiformat nicht erkannt

Natürlich sollten Sie Ihre Festplatte formatieren.

Wirklich, diese Fehler sind nicht so schwer zu lesen.


20

Ich habe Ihr Programm von PNG nach ASCII konvertiert, aber es wird noch nicht kompiliert. Zu Ihrer Information, ich habe es mit einer Zeilenbreite von 100 und 250 Zeichen versucht, aber beide liefern vergleichbare Ergebnisse.

   `         `  .     `.      `         ...                                                         
   +:: ..-.. --.:`:. `-` .....:`../--`.. `-                                                         
           `      `       ````                                                                      
                                                                      `                             
   ` `` .`       ``    .`    `.               `` .      -``-          ..                            
   .`--`:`   :::.-``-. : ``.-`-  `-.-`:.-`    :-`/.-..` `    `-..`...- :                            
   .`         ` `    ` .`         ````:``  -                  ` ``-.`  `                            
   `-                                ..                           ``                                
    .       ` .`.           `   `    `. ` .  . `    .  `    . . .` .`  `      ` ``        ` `       
           `:`.`:` ` -..-`.`-  .-`-.    /.-/.-`.-.  -...-..`- :```   `-`-`  :`..`-` ` :`.`:`- `     
            ``  `       ```.      ``    ````    `       `     `        `    `         `   `   .     
            : -...`.- .` .:/ `                                                                      
    -       `             `` .                                                                      
    -`                                                                                              
    `                                                                                               

8
Sie sollten stattdessen wahrscheinlich 80 oder sogar 72 Spalten verwenden
Tobias Kienzler

16

Das erste Problem ist, dass Sie versuchen, am Ende der Hauptfunktion einen falschen Wert zurückzugeben. Der C ++ - Standard schreibt vor, dass der Rückgabetyp von main () int ist. Stattdessen versuchen Sie, die leere Menge zurückzugeben.

Das andere Problem ist - zumindest bei g ++ -, dass der Compiler die verwendete Sprache aus dem Dateisuffix ableitet. Aus g ++ (1):

Für jede Eingabedatei bestimmt das Dateinamensuffix, welche Art der Kompilierung durchgeführt wird:

file.cc file.cp file.cxx file.cpp file.CPP file.c ++ file.C

C ++ - Quellcode, der vorverarbeitet werden muss. Beachten Sie, dass in .cxx die letzten beiden Buchstaben buchstäblich x sein müssen. Ebenso bezieht sich .C auf ein wörtliches Kapital C.

Wenn Sie diese Probleme beheben, erhalten Sie eine voll funktionsfähige Hello World-Anwendung, wie aus der Demo hier hervorgeht .


3
Ich hatte vor langer Zeit einen Professor, der Ihre Hausaufgaben oder Prüfungen ablegte, wenn Sie einen Schrägstrich durch eine Nullstelle setzen, da Null nicht die Nullmenge ist. Er würde diese Antwort schätzen.
Michael Burr

15

Ihre Schrift ist scheiße, wie sollte ein Parser das jemals lesen können? Nehmen Sie an einem Kalligraphiekurs teil.


13

Ihre Compiler erwarten ASCII , aber dieses Programm wurde offensichtlich mit EBCDIC geschrieben .


Zuletzt habe ich gehört, dass C ++ nicht spezifiziert, dass die Programme in ASCII, UTF-8 oder irgendetwas anderem geschrieben werden müssen.
Adrian Ratnapala

8

Sie versuchen, ein Bild zu kompilieren.

Geben Sie Ihre Handschrift in ein Dokument namens main.cpp ein, führen Sie diese Datei über Ihren Compiler aus und führen Sie dann die Ausgabedatei aus.


23
Überprüfen Sie das Datum auf Ihrem PC.
James P.

14
Haha, aber ich habe endlich eine einfache gefunden, die ich beantworten konnte!
Cody Gray

10
Das ist dumm. Wir alle wissen, dass der Compiler das Leerzeichen optimieren und nur stark komprimierten Schwarzraum belassen würde, der alle eins ist, und auf eine binäre 1 komprimieren würde, die als Fehler zurückgegeben würde. Der Code musste mit White-Out geschrieben werden, das auf 0 kompiliert wurde und keinen Fehler zurückgab.
der Blechmann

7

Sie müssen die Genauigkeit Ihrer Ausgabe angeben, der unmittelbar vor der endgültigen schließenden Klammer ein Doppelpunkt vorangestellt ist . Da die Ausgabe nicht numerisch ist, ist die Genauigkeit Null.

: 0}


5

hinzufügen :

using namespace std;

direkt nach dem Einschließen: P: D.


5
Ich schreibe lieber die stdganze Zeit. Erinnert mich daran, keinen zu bekommen.
Mateen Ulhaq

5

Scheint, dass Ihr Compiler keine Dateien in einer solchen hmm ... -Codierung unterstützt. Versuchen Sie es in ASCII zu konvertieren.


5

Das Problem liegt in der Syntaxdefinition. Versuchen Sie, Lineal und Kompass für eine klassischere Beschreibung zu verwenden!

Prost,


5

Versuchen Sie, die Eingangsschnittstelle zu wechseln. C ++ erwartet, dass eine Tastatur an Ihren Computer angeschlossen wird, kein Scanner. Hier kann es zu Konflikten mit Peripheriegeräten kommen. Ich habe in ISO Standard nicht überprüft, ob die Tastatureingabeschnittstelle obligatorisch ist, aber das gilt für alle Compiler, die ich jemals verwendet habe. Aber vielleicht ist die Scannereingabe jetzt in C99 verfügbar, und in diesem Fall sollte Ihr Programm tatsächlich funktionieren. Wenn nicht, müssen Sie auf die nächste Standardversion und das nächste Upgrade der Compiler warten.


5

Sie könnten verschiedene Farben für Klammern ausprobieren, vielleicht würde etwas Grün oder Rot helfen? Ich denke, Ihr Compiler kann schwarze Tinte nicht erkennen: P.


5

Bin ich der einzige, der das Zeichen zwischen 'return' und dem Semikolon nicht erkennen kann? Das könnte es sein!


4
Es ist ein Großbuchstabe O mit einer speziellen Zeile, die wir "Durchmesser" nennen und die den Compiler anweist, offensichtlich den Midpoint Circle-Algorithmus zu verwenden. Ich denke, Sie sollten Ihre Augen überprüfen lassen.
Mateen Ulhaq
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.