Pourquoi ce programme est-il rejeté par erreur par trois compilateurs C++?
j'ai quelques difficultés à compiler un programme C++ que j'ai écrit.
ce programme est très simple et, à ma connaissance, conforme à toutes les règles énoncées dans la norme C++. J'ai lu L'intégralité de la norme ISO/IEC 14882:2003 à deux reprises pour être sûr.
le programme est le suivant:
Voici la sortie que j'ai reçue en essayant de compiler ceci programme avec Visual C++ 2010:
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
consterné, j'ai essayé g++ 4.5.2, mais c'était tout aussi inutile:
c:dev>g++ helloworld.png
helloworld.png: file not recognized: File format not recognized
collect2: ld returned 1 exit status
j'ai pensé que Clang (version 3.0 tronc 127530) doivent travailler, car c'est très apprécié pour sa conformité aux normes. Malheureusement, il ne m'a même pas donné l'un de ses jolis, mis en évidence messages d'erreur:
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)
pour être honnête, je ne sais pas vraiment ce que signifie un de ces messages d'erreur.
beaucoup d'autres programmes C++ ont des fichiers source avec un .CPP extension, donc j'ai pensé que peut-être je devais renommer mon fichier. J'ai changé son nom en helloworld.rpc , mais cela n'a pas aidé. Je pense qu'il y a un bug très grave dans Clang parce que quand j'ai essayé de l'utiliser pour compiler le programme renommé, il a flippé, imprimé "84 avertissements et 20 erreurs générés."et fait de mon ordinateur bip beaucoup!
Qu'as - J'ai fait de mal ici? Est-ce que j'ai manqué une partie critique de la norme C++? Ou est-ce que les trois compilateurs sont tellement cassés qu'ils ne peuvent pas compiler ce simple programme?
30 réponses
dans la norme, §2.1/1 précise:
les caractères physiques du fichier source sont mis en correspondance, d'une manière définie par la mise en œuvre, avec le jeu de caractères de base de la source (introduction de caractères de nouvelle ligne pour les indicateurs de fin de ligne) si nécessaire.
votre compilateur ne supporte pas ce format( aka ne peut pas le mettre en correspondance avec le jeu de caractères de base ), donc il ne peut pas passer à d'autres étapes de traitement, d'où l'erreur. Il est tout à fait possible que votre compilateur supporte une correspondance de l'image au jeu de caractères source de base, mais ce n'est pas nécessaire.
puisque ce mapping est défini par la mise en œuvre, vous aurez besoin de regarder votre documentation de mise en œuvre pour voir les formats de fichiers qu'elle supporte. Typiquement, chaque fournisseur de compilateur principal soutient (canoniquement défini) des dossiers de texte: n'importe quel dossier produit par un rédacteur de texte, typiquement une série de caractères.
notez que la norme C++ est basée sur la norme C (§1.1 / 2), et la norme C(99) dit, au §1.2:
cette norme internationale ne spécifie pas
- le mécanisme par lequel les programmes C sont transformés pour l'usage d'un traitement de données système;
- le mécanisme par lequel les programmes C sont invoqués pour être utilisés par un traitement de données système;
- le mécanisme par lequel les données d'entrée sont transformées pour être utilisées par un programme C;
donc, encore une fois, le traitement des fichiers source est quelque chose que vous devez trouver dans la documentation de vos compilateurs.
Votre <
et >
, (
et )
, {
et }
ne semblent pas correspondre très bien; Essayez de le faire mieux.
vous pouvez essayer le script python suivant. Notez que vous devez installer PIL et pytesser .
from pytesser import *
image = Image.open('helloworld.png') # Open image object using PIL
print image_to_string(image) # Run tesseract.exe on image
Pour l'utiliser, faites:
python script.py > helloworld.cpp; g++ helloworld.cpp
vous avez oublié D'utiliser Comic Sans comme police, c'est pourquoi son erroring.
Je ne vois pas de nouvelle ligne après cette dernière attelle.
Comme vous le savez: "Si un fichier source qui n'est pas vide ne se termine pas par un caractère de nouvelle ligne, ... le comportement est indéfini".
ce programme est valide -- Je ne trouve aucune erreur.
je pense que vous avez un virus sur votre machine. Ce serait mieux si vous reformatez votre lecteur, et réinstallez le système d'exploitation.
Laissez-nous savoir comment cela fonctionne, ou si vous avez besoin d'aide avec le réinstaller.
je déteste les virus.
j'ai trouvé qu'il est utile de ne pas écrire mon code sur le verre de mon moniteur avec un marqueur magique, même s'il est beau quand il est vraiment noir. L'écran se remplit trop vite et puis les gens qui me donnent un moniteur propre m'appellent chaque semaine.
deux de mes employés (je suis un directeur) sont en train de m'acheter un de ces ordinateurs Red pad avec les boutons. Ils ont dit que je n'aurais pas besoin de marqueurs et je peux nettoyer l'écran moi-même quand il est plein mais je dois être attention en la secouant. Je suppose que c'est délicat de cette façon.
c'est pour ça que j'engage des gens intelligents.
File format not recognized
Vous devez formater correctement votre fichier. Cela signifie utiliser les bonnes couleurs et les bonnes polices pour votre code. Voir les documentations spécifiques pour chaque compilateur car ces couleurs varient entre les compilateurs;)
Vous avez oublié le pré-processeur. Essayez ceci:
pngtopnm helloworld.png | ocrad | g++ -x 'c++' -
avez-vous écrit le programme à la main puis l'avez-vous scanné dans l'ordinateur? C'est ce qu'implique "helloworld.png". Si c'est le cas, vous devez être conscient que la norme C++ (même dans sa dernière édition) n'exige pas la présence d'une reconnaissance optique des caractères, et malheureusement elle n'est pas incluse en option dans un compilateur actuel.
Vous pourriez envisager de transposer les graphiques dans un format textuel. Tout éditeur de texte peut être utilisé; l'utilisation d'un traitement de texte, bien que capable de générer un joli imprimé, résultera très probablement dans la même erreur que vous obtenez en essayant de scanner.
Si vous êtes vraiment aventureux, vous pouvez essayer d'écrire votre code dans un traitement de texte. Imprimez-le, de préférence en utilisant une police comme OCR-A . Ensuite, prenez votre impression et de numérisation. Le scan peut alors être exécuté à travers un paquet OCR tiers pour générer un formulaire de texte. La forme du texte peut ensuite être compilé à l'aide de l'un des nombreux compilateurs.
méfiez-vous, cependant, du coût élevé du papier que cela entraînera pendant la phase de débogage.
dessinez l'include ci-dessous pour le faire compiler:
#include <ChuckNorris>
il paraît qu'il peut compiler des erreurs de syntaxe...
malheureusement, vous avez sélectionné trois compilateurs qui prennent tous en charge Plusieurs Langues, pas seulement C++. Ils ont tous de deviner le langage de programmation utilisé. Comme vous le savez probablement déjà, le format PNG est adapté à tous les langages de programmation, et pas seulement au C++.
Habituellement, le compilateur peut comprendre le langage lui-même. Par exemple, si le PNG est évidemment dessiné avec des crayons, le compilateur saura Qu'il contient Visual Basic. Si on dirait que c'est dessiné avec un crayon mécanique, il est facile de reconnaître l'ingénieur au travail, l'écriture de code FORTRAN.
cette deuxième étape n'aide pas non plus le compilateur, dans ce cas. C et c++ semblent juste trop similaires, jusqu'au #include
. Par conséquent, vous devez aider le compilateur à décider quelle langue il est vraiment. Vous pourriez utiliser des moyens non standard. Par exemple, le compilateur Visual Studio accepte les arguments en ligne de commande /TC et /TP , ou vous pouvez utiliser Option "compiler as: C++" dans le fichier de projet. GCC et CLang ont leurs propres mécanismes, ce que je ne sais pas.
par conséquent, je recommande d'utiliser la méthode standard à la place pour dire à votre compilateur que le code suivant est en C++. Comme vous l'avez découvert, les compilateurs C++ sont très exigeants sur ce qu'ils acceptent. Par conséquent, la façon standard d'identifier C++ est par les programmeurs d'intimidation d'ajouter à leur code C++. Par exemple, la ligne suivante clarifiera pour votre compilateur que ce qui suit est C++ (et il ferait mieux de le compiler sans se plaindre).
// To the compiler: I know where you are installed. No funny games, capice?
est-ce que votre compilateur est réglé en mode expert?! Si oui, il ne devrait pas compiler. Les compilateurs modernes sont fatigués de " Hello World!"
ROC Dit:
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 _ |
_|
ce qui est sacrément bon, pour être honnête.
helloworld.png: fichier non reconnu: fichier format non reconnu
évidemment, vous devriez formater votre disque dur.
Vraiment, ces erreurs ne sont pas si difficiles à lire.
j'ai converti votre programme de PNG en ASCII, mais il n'est pas encore compilé. Pour votre information, j'ai essayé avec la largeur de ligne 100 et 250 caractères, mais les deux donnent des résultats comparables.
` ` . `. ` ...
+:: ..-.. --.:`:. `-` .....:`../--`.. `-
` ` ````
`
` `` .` `` .` `. `` . -``- ..
.`--`:` :::.-``-. : ``.-`- `-.-`:.-` :-`/.-..` ` `-..`...- :
.` ` ` ` .` ````:`` - ` ``-.` `
`- .. ``
. ` .`. ` ` `. ` . . ` . ` . . .` .` ` ` `` ` `
`:`.`:` ` -..-`.`- .-`-. /.-/.-`.-. -...-..`- :``` `-`-` :`..`-` ` :`.`:`- `
`` ` ```. `` ```` ` ` ` ` ` ` ` .
: -...`.- .` .:/ `
- ` `` .
-`
`
Le premier problème, c'est que vous essayez de renvoyer une valeur incorrecte à la fin de la fonction principale. Le standard c++ dicte que le type de retour de main () est int, mais à la place vous essayez de retourner l'ensemble vide.
l'autre problème est - au moins avec g++ - que le compilateur déduit le langage utilisé du suffixe de fichier. De G++(1):
pour tout fichier d'entrée donné, le fichier nom suffixe détermine quel type de la compilation est faite:
file.cc file.fichier cp.fichier cxx.fichier cpp.CPP file.fichier c++.C
code source C ++ qui doit être prétraité. Notez que dans .cxx, le les deux dernières lettres doivent être littéralement X. De même .C se réfère à un literal capital C.
la correction de ceux-ci devrait vous laisser avec une application Hello World entièrement fonctionnelle, comme peut être vu de la démo ici .
votre police craint, comment un analyseur devrait-il jamais être capable de lire ça? Prendre un cours de calligraphie.
vos compilateurs attendent ASCII , mais ce programme est évidemment écrit en utilisant EBCDIC .
Vous essayez de compiler une image.
tapez ce que vous avez écrit à la main dans un document appelé main.cpp, lancez ce fichier dans votre compilateur, puis lancez le fichier de sortie.
Vous devez spécifier la précision de votre sortie précédée d'un immédiatement avant la dernière accolade fermante . Comme la sortie n'est pas numérique, la précision est zéro, donc vous avez besoin de cela -
:0}
semble que votre compilateur ne supporte pas les fichiers dans un tel hmm... encodage. Essayez de le convertir en ASCII.
le problème réside dans la définition de la syntaxe, essayez d'utiliser la règle et les compas pour une description plus classique!
Cheers,
essayez l'interface d'entrée de commutation. C++ s'attend à ce qu'un clavier soit branché à votre ordinateur, pas à un scanner. Il peut y avoir des problèmes de conflits périphériques ici. Je n'ai pas vérifié dans la norme ISO si l'interface d'entrée clavier est obligatoire, mais c'est vrai pour tous les compilateurs que j'ai utilisés. Mais peut-être que l'entrée scanner est maintenant disponible en C99, et dans ce cas votre programme devrait fonctionner. Si non, vous devrez attendre la prochaine version standard et mise à niveau des compilateurs.
vous pourriez essayer différentes couleurs pour les crochets, peut-être un peu de vert ou de rouge aiderait ? Je pense que votre compilateur ne peut pas reconnaître l'encre noire: p
suis-je le seul à ne pas pouvoir reconnaître le caractère entre 'Retour' et le point-virgule? Que pourrait-il être!