【问题标题】:Is it possible to redefine main function in c是否可以在c中重新定义主要功能
【发布时间】:2014-04-05 21:40:34
【问题描述】:

我看到在 c 中使用宏重新定义函数 here。所以我很感兴趣是否可以重新定义 main 函数?

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

int main(int argc, char **argv)
{
    printf("Original main function\n");
    return 0;
}

int _main(int argc, char **argv)
{
    printf("New Original main function\n");
    return main(argc, argv);
}

#ifdef DEBUG
#define main(argc, argv) _main(argc, argv)
#endif

代码编译没有任何问题,但我得到了:

Original main function

所以我想知道为什么它不起作用?当我对mallocfree 函数使用相同的技术时,它可以完美运行。那么有什么问题呢?

为什么我想做这样的事情?我想在执行main 函数之前做一些代码。有可能以这种方式吗?如果没有,还有其他方法吗?

P.S.:对不起,我没有提到问题。我在 Ubuntu 操作系统中使用 gcc。 如果您不赞成投票,请在 cmets 中说明理由。你们的cmets对我以后的发展很有用。

【问题讨论】:

  • 我真的不明白你想在这里实现什么。如果您想在 main 之前执行代码,那么在 main 中首先执行此操作然后启动 main 程序有什么功能区别?如果真的要在main之前执行代码,必须修改crt0启动代码。在 C++ 中,您可以通过使用静态变量来实现。在调用 main 之前进行初始化。在 C 中这是不可能的。
  • 查看这个问题了解 main 的工作原理stackoverflow.com/q/19419569/2549281
  • @Devolus 我想在主函数之前使用 atexit() 注册回调函数。
  • 宏不被执行,它们被预处理。基本上,它们只是编译器在编译程序时完成的文本替换。

标签: c gcc main


【解决方案1】:

如果你的问题真的是:“我可以在 main 之前执行代码吗?” 那么答案是肯定的YES

由于您使用的是 GCC,您可以使用函数属性 (http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) 将函数标记为构造函数。

void pre_main_function (void) __attribute__ ((constructor));

一个有用的例子可以在http://www.geeksforgeeks.org/functions-that-are-executed-before-and-after-main-in-c/找到

编辑

也可以使用以下语法:

__attribute__ (( constructor(n) ))

其中n 指定优先级,允许您标记要在 main 之前执行的多个函数,同时让您控制执行顺序(n 的值越低,函数执行得越早。

【讨论】:

  • 谢谢。我会测试你的答案。
  • 它做我想要的。再次感谢您。
  • 这是GCC编译器的特性,不是C语言的特性吧?
  • 老实说,我不知道这是 GCC 扩展还是标准的一部分(并选择其中之一......)。 GCC 文档说“在 GNU C 中......”,这对我来说意味着它是一个 GCC 扩展。话虽如此,其他编译器也支持这个概念——例如 WindRiver Compiler(又名 diab)。用户指南在 ANSI C 和 C++ 的附加部分中包含了这一点。所以我认为它是一个编译器功能。
【解决方案2】:

如果您想更改程序的入口点,则无需使用定义。您可以为此使用链接器的 -e 选项:

gcc -Wl,-e,__main ...

请注意额外的下划线。根据某些选项,符号名称可能不同。

【讨论】:

  • 谢谢。我会测试你的答案。
  • 您的方法也有效,但我将使用@mjs 答案。我昨天给你投票了。对不起,我不能接受两个答案。感谢您的努力。
【解决方案3】:

您的#define 根本没有改变 main 函数 - 它是一个宏预处理器。

#define 的唯一作用是将 _main 中对 main 的调用更改为对 _main() 的递归调用。但是由于没有调用 _main,所以这是死代码。这是您的代码在预处理器运行后的样子...

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

int main(int argc, char **argv)
{
    printf("Original main function\n");
    return 0;
}

int _main(int argc, char **argv)
{
    printf("New Original main function\n");
    return _main(argc, argv); /* recursive call due to macro replace */
}

这就引出了下一个问题——这就是为什么要重新定义 main ?如果您希望在调试时运行一些完全不同的代码,只需将 main 声明为

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

int main(int argc, char **argv)
{
#ifdef DEBUG
    return debugApp( argc, argv);
#else
    return productionApp( argc, argv);
#endif
}

注意仅仅因为你可以做某事并不意味着你应该去做。 :-)

【讨论】:

  • 你能举个例子吗?
  • 为您提供扩展答案,但我要强调的是,我不认为调试代码然后运行与实际应用程序完全不同的例程是一种好习惯。
  • 感谢您的回答。我只是在检查实施的可能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多