0

可能重复:
程序执行是否总是从 C 中的 main 开始?

我想开始执行包含 2 个函数(不包括 main)的程序

void check(void)
void execute(void)

我想从 check() 开始执行,在 c/c++ 中可以吗?

4

9 回答 9

9

你可以用一个简单的包装器来做到这一点:

int main()
{
    check();
}

main由于标准明确指定为程序入口点,因此您无法以任何其他方式进行移植。

编辑评论:永远不要这样做check在 C++中,您可以在静态初始化main期间滥用静态初始化,但您仍然不能main合法地从check. 你可以先跑check。如评论中所述,这在 C 中不起作用,因为它需要常量初始化程序。

// At file scope.
bool abuse_the_language = (check(), true);

int main()
{
    // No op if desired.
}
于 2012-11-14T14:42:01.420 回答
7

各种链接器有各种选项来指定入口点。例如。Microsoft 链接器使用/ENTRY:function

/ENTRY 选项将入口点函数指定为 .exe 文件或 DLL 的起始地址。

GNU 的 ld在命令文件中使用 -e 或 ENTRY()

不用说,修改入口点是一项非常高级的功能,您必须绝对了解它的工作原理。一方面,它可能会导致跳过加载标准库初始化。

于 2012-11-14T14:45:57.780 回答
5
int main()
{
    check();
    return 0;
}
于 2012-11-14T14:42:49.183 回答
1

调用checkfrommain似乎是最合乎逻辑的解决方案,但您仍然可以探索使用/ENTRY为您的应用程序定义另一个入口点。请参阅此处了解更多信息。

于 2012-11-14T14:44:00.773 回答
1

尽管有一些方法可以在 main 之前执行一些代码,但你不能从 main 以外的东西开始。

将代码放在静态初始化块中将使代码在 main 之前运行;但是,它不会是 100% 可控的。虽然您可以确保它在 main 之前运行,但您不能指定两个静态初始化块在它们都在 main 之前执行之前运行的顺序。

链接器和加载器都具有 main 的概念,作为 C / C++ 程序的共享“理解”开始;但是,有一些代码在main. 此代码负责程序的“设置环境”(例如设置stdincin)。通过将代码放在静态初始化块中,您实际上是在说,“嘿,您也需要这样做才能拥有正确的环境”。一般来说,这应该很小,可以独立于其他项目的执行顺序。

如果你需要在 main 之前按顺序执行两三件事,那么将它们变成适当的函数并在 main 开头调用它们。

于 2012-11-14T14:45:08.217 回答
1

有一种人为的方法可以实现这一目标,但这只不过是一种黑客行为。

这个想法是创建一个包含主函数的静态库,并使其调用您的“检查”函数。链接器将在链接到您的“程序”时解析符号,并且您的“程序”代码本身确实没有 main。

不建议这样做,除非您有非常特殊的需求(一个突然想到的示例是 Windows 屏幕保护程序,因为 Windows SDK 附带的帮助程序库具有执行特定初始化的主要功能,例如解析命令行)。

于 2012-11-14T14:48:09.110 回答
1

编译器可能支持它。比如gcc,可以使用-nostartfiles和--entry=xxx来设置程序的入口点。默认入口点是_start,它将调用函数main。

于 2012-11-14T14:56:41.497 回答
0

您可以通过在 main 启动之前创建一个对象来“拦截”对 main 的调用。构造函数需要执行你的函数。

#include <iostream>

void foo()
{
  // do stuff

  std::cout<<"exiting from foo" <<std::endl;
}

struct A
{
  A(){ foo(); };
};

static A a;

int main()
{
  // something
  std::cout<<"starting main()" <<std::endl;
}
于 2012-11-14T14:45:19.303 回答
0

我找到了解决我自己问题的方法。我们可以简单地使用

#pragma startup function-name <priority>
#pragma exit function-name <priority>

这两个 pragma 允许程序指定应该在程序启动时(在调用 main 函数之前)或程序退出(就在程序通过 _exit 终止之前)调用的函数。

指定的函数名必须是先前声明的不带参数并返回 void 的函数;换句话说,它应该被声明为:

void func(void);

可选的优先级参数应该是 64 到 255 范围内的整数。最高优先级为 0。具有较高优先级的函数在启动时首先调用,最后在退出时调用。如果您不指定优先级,则默认为 100。谢谢!

于 2012-11-14T15:09:23.113 回答