什么是“非法指令:4”错误,为什么“-mmacosx-version-min=10.x”可以修复它?

91
当我在Mac OS X 10.8.2(“Mountain Lion”)下使用GCC 4.7.2编译二进制文件时,再在Mac OS X 10.7.x和早期版本下运行这些二进制文件时,会出现 “Illegal Instruction: 4” 错误。但是在Mac OS X 10.8.x下,这些二进制文件可以正常工作。
我将编译标志添加了“-mmacosx-version-min=10.5”,这似乎有助于解决10.5.x、10.6.x和10.7.x客户端的问题,不管那个问题具体是什么。
下面是我的问题:
1. “Illegal Instruction: 4”错误是什么?
2. 为什么“-mmacosx-version-min=10.x”可以解决在“10.x”及更高版本客户端上的特定错误?
我想将此修复应用于我的makefile中,但在执行之前想知道它是如何工作的。(我的二进制文件是否会更大?我的二进制文件是否仍然是64位?使用此方法是否存在需要注意的问题?是否存在意外的副作用等等。)

雪豹是Mac OSX 10.6,请澄清/更正。 - foundry
4
缺少返回值可能会导致“非法指令:4”。我昨天遇到了这个问题。注意编译器警告让我走上了正确的轨道。 - rsp1984
1
我七年前问过这个问题,但今天无法帮助你,抱歉。不过我还记得曾经尝试为旧版的Mac OS X分发二进制文件,尽管现在看来这似乎是一个愚蠢的游戏。 - Alex Reynolds
我也遇到了这个错误,迄今为止这里的建议都没有帮助。 我检查了我的编译器警告(现在它们完全消失了),尝试了-mmacosx-version-min(它是一个未被识别的选项),尝试使用clang和gcc(结果相同),并尝试不使用-O进行编译。 这不仅仅是我正在编译的程序:MacOS上的Outlook也有同样的问题。 有进一步的建议吗? - dstromberg
对不起,我希望我能帮忙! - Alex Reynolds
7个回答

44

来自苹果开发者论坛(需要账户):

"编译器和链接器能够使用一些在旧操作系统版本上无法运行的功能并进行优化。-mmacosx-version-min会告诉工具需要与哪些操作系统版本兼容,因此工具可以禁用那些在这些操作系统版本上无法运行的优化。如果您需要在旧的操作系统版本上运行,则必须使用此标志。

"-mmacosx-version-min的不足之处是,应用程序在新的操作系统版本上的性能可能比本来可以达到的要差,如果它不需要向后兼容。在大多数情况下,差异很小。"


3
将该旗帜放置的位置是在项目的构建设置中的“其他链接器标志”下,例如-mmacosx-version-min=10.10 - Demitri

25

谢谢,那两个问题和相关答案很有趣,我在提问之前已经阅读了它们,但我提出这个问题是因为它们都没有特别解决这个错误、它的原因以及为什么使用这个标志是一个解决方案。在我将其投入生产之前,我只想确保我不会为另一组用户破坏任何东西,而且我不确定是否存在任何副作用。 - Alex Reynolds
3
建议你不要担心,你正在按照系统设计师的意图进行操作。今天我看到了《编程风格之道》中的一个好引用:“试图比编译器聪明,会削弱使用编译器的许多目的。” - foundry
@foundry 一句老话,我似乎认为即使在你写这篇文章的时候也是如此。除了当你为iOCCC编写代码时,我会同意这一点!:)但是,人们确实倾向于不想处理警告等。让我困惑的是,如果他们不想修复警告,为什么还要启用警告呢?如果它是一个始终启用且无法禁用的警告,则修复该代码并完成它。否则就忽略它。但是警告是开发人员的朋友。我曾在同一系统上看到过这个非法指令4,但在Linux下(编译在那里)它可以正常工作。 - Pryftan

6

我有意识地写这篇回答来回应一个旧问题的观点,因为其他答案对我没有帮助。

在我编译后在同一系统上运行二进制文件时,出现了Illegal Instruction: 4的错误,所以-mmacosx-version-min并没有起到作用。

我在Mac OS X 10.11上使用Code Blocks 16中的gcc。

然而,关闭Code Blocks所有优化的编译标志可以解决问题。所以查看Code Blocks设置的所有标志(右键单击项目->“构建属性”),并关闭你确定不需要的所有标志,特别是-s和优化的-O标志。这对我有用。


1
我的CLI应用在原目录中工作得很好,但是当移动时会出现错误。肯定是我的代码有问题,提前退出应用程序并打印“Hello World”可以正常工作。 - Cristi Băluță
需要记住的是,优化器可以找到错误,通过禁用它们,您可能会掩盖一个错误。当然,有些代码确实不应该被优化,所以谁能说得准呢?但是,即使您决定不修复它,如果您能找到错误的源头,那也是更好的。 - Pryftan

5
我发现我的问题是一个不正确的
if (leaf = NULL) {...}
应该是
if (leaf == NULL){...}

检查一下编译器警告!


3
你知道有时候人们开玩笑地称赞= 运算符吗? "`叶子是空吗?现在是!" - Pryftan

4

3
在我的情况下,当我过载时,我遇到了这个问题。
ostream & operator << (ostream &out, const MyClass &obj)

忘记返回out。 在其他系统中,这只会生成警告,但在macOS上,它还会生成错误(尽管似乎正确打印)。

通过添加正确的返回值来解决错误。 在我的情况下,添加-mmacosx-version-min标志没有效果。


2
我最近遇到了这个错误。我使用-O3编译了二进制文件。谷歌告诉我这意味着“非法操作码”,这似乎有些可疑。然后我关闭了所有优化并重新运行。现在错误变成了段错误。因此,通过设置-g并运行valgrind,我找到了源代码并修复了它。重新启用所有优化后,没有出现非法指令4的情况。
显然,对错误的代码进行优化可能会产生奇怪的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接