【问题标题】:How can I compile and run this 1989 written C program?如何编译和运行这个 1989 年编写的 C 程序?
【发布时间】:2012-12-11 19:28:42
【问题描述】:

我发现了 Arthur Whitney 的这幅令人惊叹的作品 - http://www.jsoftware.com/jwiki/Essays/Incunabulum

编译时有一些警告

$ gcc-4.7 incuna.c -o incuna.o
incuna.c: In function 'ma':
incuna.c:8:15: warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default]
incuna.c: In function 'pi':
incuna.c:26:7: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
incuna.c: In function 'nl':
incuna.c:26:24: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
incuna.c: In function 'pr':
incuna.c:28:10: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
incuna.c: In function 'ex':
incuna.c:35:36: warning: assignment makes integer from pointer without a cast [enabled by default]
incuna.c:35:25: warning: return makes pointer from integer without a cast [enabled by default]
incuna.c: In function 'noun':
incuna.c:37:57: warning: return makes integer from pointer without a cast [enabled by default]
incuna.c: In function 'wd':
incuna.c:39:21: warning: incompatible implicit declaration of built-in function 'strlen' [enabled by default]

但在输入基本输入 1 + 1 时出现段错误。

./incuna.o
warning: this program uses gets(), which is unsafe.
1 + 1
[1]    11525 segmentation fault  ./incuna.o

我猜这与自 1989 年以来 C 编译器的差异有关。

我将如何运行它?我可以在最近的 Linux/Mac 上使用它吗?还是在 VirtualBox VM 上?还是别的什么?

我的 Google 搜索结果没有任何相关内容。

【问题讨论】:

  • 也许您可以尝试在 gdb 中运行该程序以查看更多信息?
  • #include <stdio.h> 也许?编辑:更正语法
  • 这看起来像是由于 gets() 导致的缓冲区溢出
  • 1+1 没有段错误。只是觉得你应该知道。
  • @leppie,添加它,结果相同。

标签: c gcc compiler-construction vm-implementation


【解决方案1】:

它将指针转换为intlong,反之亦然。这与具有不同大小的 64 位架构不同。

为 32 位目标编译它。例如,在 Mac OS X 上使用 clang/LLVM 使用“-arch i386”。

【讨论】:

  • -m32 用于 gcc。这可能是非 64 位安全程序的一个很好的例子。 ;)
【解决方案2】:

我敢打赌它是因为这个而出现段错误的:

incuna.c:8:15:警告:内置函数“malloc”的隐式声明不兼容[默认启用]

如果 malloc 没有被声明,那么它就不会为你分配内存,你最终会取消对 null 的引用,这可能会导致段错误。

包括后:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

printf()malloc()strlen() 的警告已消失。如果您输入,代码将运行并工作:

1+1

注意间距很重要

1 + 1 

会出现段错误。

【讨论】:

  • 您可能忘记包含
  • @SSHThis,包括 stdlib 删除了警告,但段错误仍然存​​在。
  • 太棒了!这个和 Eric 下面的答案使用 i386 arch 在我的 64 位环境中工作:)
  • 添加#include &lt;string.h&gt; 也为strlen() 提供声明。
  • 不声明 malloc() 不会导致它返回零并且以某种方式无法分配内存!如果程序仍然正确链接,则 malloc() 仍然存在并且被调用,尽管正如正确答案中指出的那样,如果指针和 int 的大小不同,则返回值可能会被错误地处理。
【解决方案3】:

仅通过预处理器运行它:

gcc -E interp.c > interp-pp.c

然后在编辑器中美化它,然后使用调试器观察它的作用。

【讨论】:

    【解决方案4】:

    在我的系统(AMD64 Win 8)上,似乎指针值通常设置了最高位,因此将指针视为整数(该程序会这样做)会行为不端并崩溃。

    更改qv(a) 函数(“查询动词”)允许程序运行:

    qv(a){R a<'a';}
    

    应该是

    qv(a){R a<'a'&&a>0;}
    

    qv(a)unsigned a;{R a<'a';}
    

    这是一个指向 minimally-modified version 的链接,它应该在没有警告的情况下编译(使用 gcc,默认选项)并执行(使用正确的输入)。

    【讨论】:

    • 我创建了一个 github 项目,扩展了这个奇怪的小程序。 link
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    相关资源
    最近更新 更多