【问题标题】:C code setjmp declare functions?C代码setjmp声明函数?
【发布时间】:2018-07-15 17:11:26
【问题描述】:

我绝对不是程序员,但我正在尝试让一个非常古老的程序从 fortran 编译到 C,这样我就可以玩一个我 20 多年没玩过的游戏(最初是在 HP3000 上创建的在 70 年代后期!)在我的 linux 机器上。

有人编写了一个 make.sh 文件,使用 f2c(fortran 到 C),以便它可以在 linux 下使用 GCC 进行编译,但这是很久以前完成的。

我收到以下错误消息:

stubs.c: In function ‘exexc_’:
stubs.c:76:13: warning: implicit declaration of function ‘mmsa_’; did 
you mean ‘memset’? [-Wimplicit-function-declaration]
case 'A': mmsa_(); break;

stubs.c 中的相关代码,即 exexc 函数是:

#include <setjmp.h>
int setjmp(jmp_buf env);
void exexc_(name, i1, i2, i3, i4, i5, namelen)
char *name;
shortint *i1, *i2, *i3, *i4, *i5;
long namelen;
 {
   static jmp_buf env;
   static int first = 1;
   static char segment[6];

   ipx[0] = *i1;
   ipx[1] = *i2;
   ipx[2] = *i3;
   ipx[3] = *i4;
   ipx[4] = *i5;

   strncpy(segment, name, namelen);

   if( ! first ) longjmp(env, 1);

   if( first )
  {
            first = 0;
            setjmp(env);
            switch(segment[3]) {
            case 'A': mmsa_(); break;
            case 'B': mmsb_(); break;
            case 'C': mmsc_(); break;
            case 'D': mmsd_(); break;
            case 'E': mmse_(); break;
            case 'F': mmsf_(); break;
            case 'G': mmsg_(); break;
            case 'H': mmsh_(); break;
            case 'I': mmsi_(); break;
            case 'J': mmsj_(); break;
            case 'K': mmsk_(); break;
            case 'L': mmsl_(); break;
            default:
                  fprintf(stderr, "Whoa, attempted to call segment %s\n", segment);
                  fflush(stderr);
                   exit(1);
           }
          fprintf(stderr, "Oops, segment %s didn't call next segment\n", segment);
          fflush(stderr);
          exit(2);
   }
}

我需要在 stubs.c 文件中进行哪些更改,以便声明 'case 'A': mmsa_()' 函数?如果有帮助,那么 mmsa 指的是我认为 mmsa.c 在同一本地目录中的另一个文件。

如果您需要,很乐意提供更多信息。我已经 20 多年没有玩过这个游戏了(!),所以任何帮助都将不胜感激。

【问题讨论】:

  • 如果您有 mmsxxx 函数的代码,则必须声明它们:void mmsa_(); 或包含相关的 .h 文件(如果存在)。
  • 这不是错误信息;这只是一个警告。
  • 非常感谢大家 :) 现在可以正确编译了 :)
  • 在 C89 模式下构建(-ansi 切换 gcc),您可以禁用或忽略警告
  • 为什么不直接安装 Fortran 编译器并使用原始代码?

标签: c setjmp


【解决方案1】:

这“只是”一个警告,函数调用没有任何参数,也没有检索到任何返回值,所以写起来应该是安全的:

void mmsa_(void);
void mmsb_(void);
...

等等。

如果你有头文件来声明这些函数,那就更好了,因为你可以包含它们而不是直接声明它们。

当然你必须链接到包含mmsa_代码和其他函数的库或对象,否则你会得到一个链接错误(问题会被转移到链接阶段)

顺便说一句:考虑重构您的代码以删除非常过时且容易出错的 K&R 旧式参数声明。

【讨论】:

  • 这些是无效的(非原型)函数声明。空参数列表由void 指定,而不是空括号。
  • 我认为它“太多了”。你是对的。否则,可以传递参数。
  • TBH,这个问题非常没有希望。如果 OP 不知道 C 并且代码很古老,在使用之前不声明函数,那么很可能还有其他更微妙的怪癖。我建议要么使用 fortran 编译器(gcc 确实提供了一个),要么以此为契机从一本好的教科书中学习 C。单独一个标准库函数的自定义声明是非法的。所有static 局部变量也是。自动翻译的代码只是 urgh。 (另外:我们不知道函数应该做什么,特别是显示代码中的所有副作用)。
  • 最后:K&R参数声明也无效。
  • 在 C89 中添加这些原型可能会引入未定义的行为,具体取决于函数的定义方式
猜你喜欢
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
相关资源
最近更新 更多