我可以从GCC中的变量名称知道数据类型吗?

时间:2013-07-16 00:40:07

标签: gcc

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

我的最终目标是获取函数签名以创建函数存根(骨架代码)

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

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

例如,foo.c如下所示

#include <stdio.h>

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

我想创建一个函数存根

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

我该怎么办?

我想在下面:

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

  2. 阅读第5行

    n = foo();

  3. 使用符号表

  4. 检查n的类型

    是不是?

    抱歉我的英文不好

    请教我推理功能签名

4 个答案:

答案 0 :(得分: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)。

答案 1 :(得分:0)

似乎没问题,但这种策略不够好。使用表达式的左侧不足以确定函数的返回类型。特别是,可能根本没有左侧,只需:foo();。那么呢?

答案 2 :(得分:0)

如果您只想查看符号表,那就是nm的用途。

例如,如果您将foo.obar.o链接在一起时出错,则可以执行此操作:

nm -a foo.o

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

但我不明白为什么你认为这会有所帮助。 C符号没有任何类型信息。可能有足够的元数据来区分外部链接,和/或判断符号功能或数据,但就是这样。无法通过int告诉float,或者从int获取double并从函数中返回char *的函数返回不同的char *

答案 3 :(得分:0)

所以,你有一些名为foo的函数已定义某处,你想知道它的类型是什么。

如果您的foo d头文件中某处没有#include的原型,这很容易:

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

这不是那些“技术上无效,但它适用于每个平台”案例;它打破。例如,使用gcc 4.2 for 64-bit x86 linux或Mac,如果你这样做:

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或一些随机未初始化的值 - 但它不能将它返回给你;它被隐藏在调用者不知道访问的任意浮点寄存器中。)< / p>


如果头文件中的 ,您始终可以搜索它。 emacs,图形IDE等都非常擅长这一点。但是你可以用两种方式使用编译器来帮助你。

首先,这样做:

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

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

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