1

我想知道使用变量名的数据类型

我的最终目标是获得用于制作函数存根(骨架代码)的函数签名

但 GCC 错误消息只通知未定义的函数名

我可以看到一个符号表吗?(用于推理功能签名)

例如, foo.c 如下所示

#include <stdio.h>

int main() {
    int n = 0;
    n = foo();
    return 0;
}

我想做一个函数存根

所以我想知道函数 foo 没有参数并返回一个整数值

我该怎么办?

我认为如下:

  1. 链接器错误消息说函数 foo 未定义

  2. 读取第 5 行

    n = foo();

  3. 使用符号表检查 n 的类型

这样对吗?

对不起,我的英语不好

请教我推断函数签名

4

4 回答 4

2

将他的代码注入到你的源文件中:

typedef struct { int a; char c; } badtype_t;
badtype_t badtype;

然后像这样替换错误行:

n = badtype; //foo();

或者如果您希望类型foo返回:

badtype = foo();

那么你会得到一些像这样的错误:

incompatible types when initializing type ‘int’ using type ‘badtype_t’

你可以得到类型int

或者如果你想要foo它自己的类型:

foo * 2

那么你会得到一些像这样的错误:

invalid operands to binary * (have 'int (*)()' and 'int')

并且您可以获得类型int (*)()(即,函数不接受任何内容并返回一个 int)。

于 2013-07-16T00:59:23.007 回答
0

看起来还可以,但这种策略还不够好。使用表达式的左侧不足以确定函数的返回类型。特别是,可能根本没有左侧,简单地说:foo();. 然后怎样呢?

于 2013-07-16T00:45:14.303 回答
0

如果你只是想看一个符号表,这就是nm目的。

例如,如果你得到一个错误链接foo.obar.o在一起,你可以这样做:

nm -a foo.o

这将显示模块中定义的所有符号foo

但我不明白你为什么认为这会有所帮助。C 符号没有任何类型信息。可能有足够的元数据来区分外部链接,和/或判断是符号函数还是数据,仅此而已。没有办法区分 aint和 a float,或者一个接受两个ints 并返回 adouble的函数与一个接受 achar *并返回一个不同的函数char *

于 2013-07-16T00:57:32.193 回答
0

因此,您在某处foo定义了一些名为的函数,并且您想知道它的类型是什么。

foo如果您的 d 头文件中的某个位置实际上没有原型#include,这很容易:

  • 如果您使用的是 C99,则您的代码无效。
  • 否则,foo必须不带参数并返回int,否则您的代码无效。

这不是那些“技术上无效,但它适用于每个平台”的案例之一;它破裂。例如,对于 64 位 x86 linux 或 Mac,使用 gcc 4.2,如果您这样做:

double foo(double f) { return f*2; }

然后,没有头文件,这样调用它:

double f = foo(2.0);
printf("%f\n", f);

如果编译为 C89,这将很好地编译和链接(clang 或 gcc 4.8 会给你一个警告;默认情况下 gcc 4.2 甚至不会这样做),然后运行并打印出2.0. 至少在 x86_64 上;在 ARM7 上,如果幸运的话,你会破坏堆栈和段错误。(当然,它实际上会加倍一些东西——你的 2.0 或一些随机的未初始化值——但它不能把它返回给你;它把它藏在调用者不知道要访问的任意浮点寄存器中。)


如果它头文件中,您可以随时搜索它。emacs、图形 IDE 等在这方面非常擅长。但是您可以通过两种方式使用编译器来帮助您。

首先,只需这样做:

gcc -E main.c > main.i
less main.i

现在搜索/foo,您会找到它。

或者你可以欺骗编译器给你一个错误信息,就像 perreal 的回答一样。

于 2013-07-16T01:24:01.340 回答