为什么这个程序会被三个 C++ 错误地拒绝?编译器?
我在编译我编写的 C++ 程序时遇到一些困难。
该程序非常简单,并且据我所知,符合 C++ 标准中规定的所有规则。为了确定这一点,我已经完整阅读了 ISO/IEC 14882:2003 两遍。
该程序如下:
这是我尝试使用 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
沮丧的是,我尝试了 g++ 4.5.2,但它同样没有帮助:
c:\dev>g++ helloworld.png
helloworld.png: file not recognized: File format not recognized
collect2: ld returned 1 exit status
我认为 Clang(版本 3.0 trunk 127530)一定可以工作,因为它因其标准一致性而受到高度赞扬。不幸的是,它甚至没有给我一个漂亮的、突出显示的错误消息:
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)
说实话,我真的不知道这些错误消息是什么意思。
许多其他 C++ 程序都有带有 .cpp 扩展名的源文件,所以我想也许我需要重命名我的文件。我将其名称更改为 helloworld.cpp,但这没有帮助。我认为 Clang 中有一个非常严重的错误,因为当我尝试使用它来编译重命名的程序时,它崩溃了,打印出“生成了 84 个警告和 20 个错误”。并让我的电脑发出很多嘟嘟声!
我在这里做错了什么?我是否错过了 C++ 标准的某些关键部分?或者这三个编译器真的都太糟糕了以至于无法编译这个简单的程序吗?
I am having some difficulty compiling a C++ program that I've written.
This program is very simple and, to the best of my knowledge, conforms to all the rules set forth in the C++ Standard. I've read over the entirety of ISO/IEC 14882:2003 twice to be sure.
The program is as follows:
Here is the output I received when trying to compile this program with 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
Dismayed, I tried g++ 4.5.2, but it was equally unhelpful:
c:\dev>g++ helloworld.png
helloworld.png: file not recognized: File format not recognized
collect2: ld returned 1 exit status
I figured that Clang (version 3.0 trunk 127530) must work, since it is so highly praised for its standards conformance. Unfortunately, it didn't even give me one of its pretty, highlighted error messages:
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)
To be honest, I don't really know what any of these error message mean.
Many other C++ programs have source files with a .cpp extension, so I thought perhaps I needed to rename my file. I changed its name to helloworld.cpp, but that didn't help. I think there is a very serious bug in Clang because when I tried using it to compile the renamed program, it flipped out, printed "84 warnings and 20 errors generated." and made my computer beep a lot!
What have I done wrong here? Have I missed some critical part of the C++ Standard? Or are all three compilers really just so broken that they can't compile this simple program?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
最初来自 概述@reddit。
Originally from Overv @ reddit.
尝试这种方式:
Try this way:
您的
<
和>
、(
和)
、{
和}
似乎不太匹配;尝试把它们画得更好。Your
<
and>
,(
and)
,{
and}
don't seem to match very well; Try drawing them better.在该标准中,§2.1/1 规定:
您的编译器不支持该格式(也称为无法将其映射到基本源字符集),因此它无法进入进一步的处理阶段,因此会出现错误。您的编译器完全有可能支持从图像到基本源字符集的映射,但这不是必需的。
由于此映射是实现定义的,因此您需要查看实现文档以了解它支持的文件格式。通常,每个主要编译器供应商都支持(规范定义的)文本文件:文本编辑器生成的任何文件,通常是一系列字符。
请注意,C++ 标准基于 C 标准 (§1.1/2),并且 C(99) 标准在 §1.2 中表示:
因此,再次强调,源文件的处理是您需要在编译器文档中找到的内容。
In the standard, §2.1/1 specifies:
Your compiler doesn't support that format (aka cannot map it to the basic source character set), so it cannot move into further processing stages, hence the error. It is entirely possible that your compiler support a mapping from image to basic source character set, but is not required to.
Since this mapping is implementation-defined, you'll need to look at your implementations documentation to see the file formats it supports. Typically, every major compiler vendor supports (canonically defined) text files: any file produced by a text editor, typically a series of characters.
Note that the C++ standard is based off the C standard (§1.1/2), and the C(99) standard says, in §1.2:
So, again, the treatment of source files is something you need to find in your compilers documentation.
您可以尝试以下 python 脚本。请注意,您需要安装 PIL 和 pytesser。
要使用它,请执行以下操作:
You could try the following python script. Note that you need to install PIL and pytesser.
To use it, do:
您忘记使用 Comic Sans 作为字体,这就是它出错的原因。
You forgot to use Comic Sans as a font, that's why its erroring.
在最后一个大括号之后我看不到换行符。
如您所知:“如果非空的源文件不以换行符结尾,...行为未定义”。
I can't see a new-line after that last brace.
As you know: "If a source file that is not empty does not end in a new-line character, ... the behavior is undefined".
这个程序是有效的——我没有发现任何错误。
我的猜测是你的机器上有病毒。最好重新格式化驱动器并重新安装操作系统。
请告诉我们结果如何,或者您是否需要重新安装方面的帮助。
我讨厌病毒。
This program is valid -- I can find no errors.
My guess is you have a virus on your machine. It would be best if you reformat your drive, and reinstall the operating system.
Let us know how that works out, or if you need help with the reinstall.
I hate viruses.
我发现不用用魔术笔在显示器玻璃上写代码会很有帮助,尽管它在真正黑色的时候看起来很不错。屏幕填满的速度太快,然后每周给我干净显示器的人都会骂我。
我的几个员工(我是一名经理)正在出钱给我买一台带旋钮的红垫电脑。他们说我不需要记号笔,当屏幕满了时我可以自己清洁屏幕,但我必须小心摇动它。我想这样很微妙。
这就是我雇用聪明人的原因。
I've found it helps to not write my code on my monitor's glass with a magic marker, even though it looks nice when its really black. The screen fills up too fast and then the people who give me a clean monitor call me names each week.
A couple of my employees (I'm a manager) are chipping in to buy me one of those red pad computers with the knobs. They said that I won't need markers and I can clean the screen myself when it's full but I have to be careful shaking it. I supposed it's delicate that way.
That's why I hire the smart people.
无法识别文件格式
您需要正确设置文件格式。这意味着为您的代码使用正确的颜色和字体。请参阅每个编译器的具体文档,因为这些颜色因编译器而异;)File format not recognized
You need to properly format your file. That means using the right colors and fonts for your code. See the specific documentations for each compiler as these colors vary between compiler ;)你忘记了预处理器。试试这个:
You forgot the pre-processor. Try this:
你是手写程序然后扫描到电脑里吗?这就是“helloworld.png”所暗示的内容。如果是这种情况,您需要注意 C++ 标准(即使是最新版本)不需要光学字符识别,不幸的是,它没有作为可选功能包含在任何当前的编译器中。
您可能需要考虑将图形转换为文本格式。可以使用任何纯文本编辑器;使用文字处理器虽然能够生成漂亮的打印输出,但很可能会导致与尝试扫描时遇到的错误相同的错误。
如果您确实有冒险精神,您可以尝试将代码写入文字处理器。打印它,最好使用 OCR-A 等字体。然后,取出打印输出并将其扫描回来。然后可以通过第三方 OCR 包运行扫描以生成文本表单。然后可以使用许多标准编译器之一来编译文本形式。
但请注意,在调试阶段这将产生大量的纸张成本。
Did you handwrite the program and then scan it into the computer? That is what is implied by "helloworld.png". If that is the case, you need to be aware that the C++ standard (even in its newest edition) does not require the presence of optical character recognition, and unfortunately it is not included as an optional feature in any current compiler.
You may want to consider transposing the graphics to a textual format. Any plain-text editor may be used; the use of a word processor, while capable of generating a pretty printout, will most likely result in the same error that you get while trying to scan.
If you are truly adventurous, you may attempt to write your code into a word processor. Print it, preferably using a font like OCR-A. Then, take your printout and scan it back in. The scan can then be run through a third-party OCR package to generate a text form. The text form may then be compiled using one of many standard compilers.
Beware, however, of the great cost of paper that this will incur during the debugging phase.
绘制下面的包含以使其编译:
我听说他可以编译语法错误......
Draw the include below to make it compile:
I hear he can compile syntax errors...
不幸的是,您选择了三个编译器,它们都支持多种语言,而不仅仅是 C++。他们都必须猜测你使用的编程语言。您可能已经知道,PNG 格式适用于所有编程语言,而不仅仅是 C++。
通常编译器可以弄清楚语言本身。例如,如果 PNG 明显是用蜡笔绘制的,编译器就会知道它包含 Visual Basic。如果它看起来像是用自动铅笔绘制的,那么很容易认出正在工作的正在编写 FORTRAN 代码的工程师。
在这种情况下,第二步对编译器也没有帮助。 C 和 C++ 看起来太相似了,就连
#include
也不例外。因此,您必须帮助编译器确定它到底是什么语言。现在,您可以使用非标准手段。例如,Visual Studio 编译器接受 /TC 和 /TP 命令行参数,或者您可以在项目文件中使用“编译为:C++”选项。 GCC和CLang有自己的机制,我不知道。因此,我建议使用标准方法来告诉编译器以下代码是 C++ 语言。正如您现在所发现的,C++ 编译器对于它们接受的内容非常挑剔。因此,识别 C++ 的标准方法是通过将恐吓程序员添加到他们的 C++ 代码中。例如,下面的行将向您的编译器澄清接下来是 C++(并且他最好毫无抱怨地编译它)。
Unfortunately, you have selected three compilers that all support multiple languages, not just C++. They all have to guess at the programming language you used. As you probably already know, the PNG format is suitable for all programming languages, not just C++.
Usually the compiler can figure out the language itself. For instance, if the PNG is obviously drawn with crayons, the compiler will know it contains Visual Basic. If it looks like it's drawn with a mechanical pencil, it's easy to recognize the engineer at work, writing FORTRAN code.
This second step doesn't help the compiler either, in this case. C and C++ just look too similar, down to the
#include
. Therefore, you must help the compiler decide what language it really is. Now, you could use non-standard means. For instance, the Visual Studio compiler accepts the /TC and /TP command-line arguments, or you could use the "Compile as: C++" option in the project file. GCC and CLang have their own mechanisms, which I don't know.Therefore, I'd recommend using the standard method instead to tell your compiler that the code following is in C++. As you've discovered by now, C++ compilers are very picky about what they accept. Therefore the standard way to identify C++ is by the intimidation programmers add to their C++ code. For instance, the following line will clarify to your compiler that what follows is C++ (and he'd better compile it without complaints).
试试这个:
Try this one:
您的编译器是否设置为专家模式?!如果是,则不应编译。现代编译器厌倦了“Hello World!”
Is your compiler set in expert mode?! If yes, it shouldn't compile. Modern compilers are tired of "Hello World!"
OCR 说:
公平地说,这非常好。
OCR Says:
Which is pretty damn good, to be fair.
显然,您应该格式化硬盘。
确实,这些错误并不难读。
Obviously, you should format your hard drive.
Really, these errors aren't that hard to read.
我确实将你的程序从 PNG 转换为 ASCII,但它还没有编译。供您参考,我确实尝试使用 100 和 250 个字符的行宽,但两者都产生了类似的结果。
I did convert your program from PNG to ASCII, but it does not compile yet. For your information, I did try with line width 100 and 250 characters but both yield in comparable results.
第一个问题是,您试图在主函数末尾返回不正确的值。 C++ 标准规定 main() 的返回类型是 int,但您却试图返回空集。
另一个问题是 - 至少对于 g++ - 编译器从文件后缀推断出使用的语言。来自 g++(1):
解决这些问题后,您将得到一个完全正常工作的 Hello World 应用程序,如此处。
The first problem is, that you are trying to return an incorrect value at the end of the main function. C++ standard dictates that the return type of main() is int, but instead you are trying to return the empty set.
The other problem is - at least with g++ - that the compiler deduces the language used from the file suffix. From g++(1):
Fixing these should leave you with a fully working Hello World application, as can be seen from the demo here.
你的字体很糟糕,解析器如何能够读取它?参加书法课程。
Your font sucks, how should a parser ever be able to read that? Take a calligraphy course.
您的编译器需要 ASCII,但该程序显然是使用 EBCDIC 编写的。
Your compilers are expecting ASCII, but that program is obviously written using EBCDIC.
您正在尝试编译图像。
将您手写的内容输入到名为 main.cpp 的文档中,通过编译器运行该文件,然后运行输出文件。
You're trying to compile an image.
Type out what you've hand written into a document called main.cpp, run that file through your compiler, then run the output file.
您需要指定输出的精度,并在最后的右大括号之前加一个冒号。。由于输出不是数字,精度为零,因此您需要 -
:0}
You need to specify the precision of your output preceded by a colon immediately before the final closing brace. Since the output is not numeric, the precision is zero, so you need this-
:0}
看来您的编译器不支持这种嗯...编码的文件。尝试将其转换为 ASCII。
Seems that your compiler doesn't support files in such hmm... encoding. Try to convert it to ASCII.
问题出在语法定义上,尝试使用尺子和圆规进行更经典的描述!
干杯,
The problem lies with the syntax definition, try using ruler and compasses for a more classical description!
Cheers,
尝试切换输入界面。 C++ 期望将键盘插入您的计算机,而不是扫描仪。这里可能存在外设冲突问题。我没有检查 ISO 标准是否强制要求键盘输入接口,但对于我使用过的所有编译器都是如此。但也许扫描仪输入现在可以在 C99 中使用,在这种情况下,您的程序应该确实可以工作。如果没有,您将不得不等待下一个标准版本和编译器升级。
Try switching input interface. C++ expects a keyboard to be plugged in to your computer, not a scanner. There may be peripherals conflict issues here. I didn't check in ISO Standard if keyboard input interface is mandatory, but that is true for all compilers I ever used. But maybe scanner input is now available in C99, and in this case your program should indeed work. If not you'll have to wait the next standard release and upgrade of compilers.
您可以尝试不同颜色的括号,也许一些绿色或红色会有帮助?
我认为你的编译器无法识别黑色墨水:P
You could try different colors for brackets, maybe some green or red would help ?
I think your compiler can't rcognize black ink :P
我是唯一一个认不出“return”和分号之间的字符的人吗?可能就是这样!
Am I the only one who can't recognize the character between 'return' and the semicolon? That could be it!
添加 :
紧接在包含 :P:D 之后
add :
right after include :P:D