C++ 是否可以在不使用 main() 函数的情况下编写程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7050925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:25:07  来源:igfitidea点击:

Is it possible to write a program without using main() function?

c++ccompilationmain

提问by Expert Novice

I keep getting this question asked in interviews:

我在面试中不断被问到这个问题:

Write a program without using main()function?

编写程序而不使用main()函数?

One of my friends showed me some code using Macros, but i could not understand it.

我的一位朋友向我展示了一些使用宏的代码,但我无法理解。

So the question is:

所以问题是:

Is it really possible to write and compile a program without main()?

真的可以编写和编译没有 的程序main()吗?

采纳答案by Cheers and hth. - Alf

Within standard C++ a mainfunction is required, so the question does not make sense for standard C++.

在标准 C++main中需要一个函数,所以这个问题对标准 C++ 没有意义。

Outside of standard C++ you can for example write a Windows specific program and use one of Microsoft's custom startup functions (wMain, winMain, wWinmain). In Windows you can also write the program as a DLL and use rundll32 to run it.

例如,在标准 C++ 之外,您可以编写 Windows 特定程序并使用 Microsoft 的自定义启动函数之一(wMain、winMain、wWinmain)。在 Windows 中,您还可以将程序编写为 DLL 并使用 rundll32 来运行它。

Apart from that you can make your own little runtime library. At one time that was a common sport.

除此之外,您可以制作自己的小型运行时库。曾几何时,这是一项常见的运动。

Finally, you can get clever and retort that according to the standard's ODR rule mainisn't "used", so any program qualifies. Bah! Although unless the interviewers have unusual good sense of humor (and they wouldn't have asked the question if they had) they'll not think that that's a good answer.

最后,你可以聪明地反驳说,根据标准的 ODR 规则main没有“使用”,因此任何程序都有资格。呸! 虽然除非面试官有不同寻常的幽默感(如果他们有的话,他们就不会问这个问题)他们不会认为这是一个很好的答案。

回答by Alok Save

No you cannot unless you are writing a program in a freestanding environment(embedded environment OS kernel etc.) where the starting point need not be main(). As per the C++ standard main()is the starting point of any program in a hosted environment.

不,除非您freestanding environment在起点不需要的(嵌入式环境操作系统内核等)中编写程序,否则您不能main()。根据 C++ 标准main(),任何程序的起点都是hosted environment.

As per the:

根据:

C++03 standard 3.6.1 Main function

C++03 标准3.6.1 Main 函数

1 A program shall contain a global function called main, which is the designated start of the program. It is implementation-defined whether a program in a freestanding environment is required to define a main function. [ Note: In a freestanding environment, start-up and termination is implementation-defined; startup contains the execution of constructors for objects of namespace scope with static storage duration; termination contains the execution of destructors for objects with static storage duration.

1 程序应包含一个名为 main 的全局函数,它是程序的指定开始。独立环境中的程序是否需要定义主函数是实现定义的。[注意:在独立环境中,启动和终止是实现定义的;启动包含对具有静态存储持续时间的命名空间范围对象的构造函数的执行;终止包含对具有静态存储持续时间的对象执行析构函数。



What is freestanding Environment& What is Hosted Environment?
There are two kinds of conforming implementations defined in the C++ standard; hostedand freestanding.

什么是freestanding Environment&什么是Hosted Environment
C++ 标准中定义了两种符合要求的实现;hostedfreestanding

A freestandingimplementation is one that is designed for programs that are executed without the benefit of an operating system.
For Ex: An OS kernel or Embedded environment would be a freestanding environment.

一个freestanding实现是一个专为那些没有操作系统的好处执行的程序。
例如:操作系统内核或嵌入式环境将是一个独立的环境。

A program using the facilities of an operating system would normally be in a hosted implementation.

使用操作系统功能的程序通常位于hosted implementation.

From the C++03 Standard Section 1.4/7:

来自 C++03 标准第 1.4/7 节:

A freestanding implementation is one in which execution may take place without the benefit of an operating system, and has an implementation-defined set of libraries that includes certain language-support libraries.

独立实现是一种可以在没有操作系统优势的情况下执行的实现,并且具有一组实现定义的库,其中包括某些语言支持库。

Further,
Section: 17.4.1.3.2 Freestanding implementationsquotes:

此外,
第:17.4.1.3.2 独立实现引用:

A freestanding implementation has an implementation-defined set of headers. This set shall include at least the following headers, as shown in Table:

独立的实现有一组实现定义的头文件。该集合至少应包括以下标题,如表所示:

18.1 Types <cstddef>   
18.2 Implementation properties <limits>   
18.3 Start and termination <cstdlib> 
18.4 Dynamic memory management <new> 
18.5 Type identification <typeinfo> 
18.6 Exception handling <exception> 
18.7 Other runtime support <cstdarg>

回答by miku

Sample program without a visiblemain function.

没有可见主函数的示例程序。

/* 
    7050925.c 
    $ gcc -o 7050925 7050925.c
*/

#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
        printf("How mainless!\n");
}

From: http://learnhacking.in/c-program-without-main-function/

来自:http: //learnhacking.in/c-program-without-main-function/

回答by phoxis

mainmeans an entry point, a point from which your code will start executing. although mainis not the first function to run. There are some more code which runs before mainand prepares the environment to make your code run. This code then calls main. You can change the name of the mainfunction by recompiling the code of the startup file crt0.cand changing the name of the mainfunction. Or you can do the following:

main表示入口点,您的代码将从该点开始执行。虽然main不是第一个运行的函数。还有一些代码在之前运行main并准备环境以使您的代码运行。此代码然后调用main. 您可以main通过重新编译启动文件的代码crt0.c并更改main函数名称来更改函数名称。或者您可以执行以下操作:

#include <stdio.h>

extern void _exit (register int code);

_start()
{
  int retval;
  retval = my_main ();
  _exit(retval);
}

int my_main(void)
{
  printf("Hello\n");
  return 0;
}

Compile the code with:

使用以下代码编译代码:

gcc -o no_main no_main.c -nostartfiles

The -nostartfileswill not include the default startup file. You point to the main entry file with the _start.

-nostartfiles不包括默认的启动文件。您指向带有_start.

mainis nothing but a predefined entrypoint for the user code. Therefore you can name it whatever, but at the end of the day you do need an entry point. In C/C++ and other languages the name is selected as mainif you make another language or hack the sources of these language compilers then you can change the name of mainto painbut it will bring pain, as it will violate the standards.

main只不过是用户代码的预定义入口点。因此,您可以随意命名,但归根结底,您确实需要一个入口点。在C / C ++和其他语言的名称被选为main如果你把另一种语言或破解这些语言编译器的源代码,那么你可以更改名称mainpain,但它会带来痛苦,因为这将违反标准。

But manipulating the entry function name is useful for kernel code, the first function to run in the kernel, or code written for embedded systems.

但是操作入口函数名称对于内核代码、内核中运行的第一个函数或为嵌入式系统编写的代码很有用。

回答by Johannes Schaub - litb

They may refer to a program written for a freestanding implementation. The C++ Standard defines two sorts of implementations. One is a hostedimplementation. Programs written for those implementations are required to have a mainfunction. But otherwise, no mainfunction is required if the freestanding implementation doesn't require one. This is useful for operation system kernels or embedded system programs that don't run under an operation system.

他们可能指的是为独立实现而编写的程序。C++ 标准定义了两种实现。一种是托管实现。为这些实现编写的程序需要有一个main函数。但除此之外,main如果独立实现不需要一个功能,则不需要任何功能。这对于不在操作系统下运行的操作系统内核或嵌入式系统程序很有用。

回答by DigitalRoss

Yes

是的

$ cat > hwa.S
write = 0x04
exit  = 0xfc
.text
_start:
        movl    , %ebx
        lea     str, %ecx
        movl    $len, %edx
        movl    $write, %eax
        int     
Mac:~/so$ cat > nomain.S
.text
.globl start
start:
        call   _notmain
Mac:~/so$ as -o nomain.o nomain.S
Mac:~/so$ cat > notmain.c
#include <unistd.h>

void notmain(void) {
  write(1, "hi\n", 3);
  _exit(0);
}
Mac:~/so$ cc -c notmain.c
Mac:~/so$ ld -w nomain.o notmain.o -lc
Mac:~/so$ ./a.out
hi
x80 xorl %ebx, %ebx movl $exit, %eax int
 g++ -c noMain.cpp -o noMain.o
x80 .data str: .ascii "Hello, world!\n" len = . -str .globl _start $ as -o hwa.o hwa.S $ ld hwa.o $ ./a.out Hello, world!

The kernel that really runs an executable knows nothing about internal symbols, it just transfers to an entry point specified in binary in the executable image header.

真正运行可执行文件的内核对内部符号一无所知,它只是传输到可执行映像标头中以二进制指定的入口点。

The reason you need a main is because normally your "main program" is really just another module. The entry point is in library-provided startup code written in some combination of C and assembly and that library code just happens to call mainso you normally need to provide one. But run the linker directly and you don't.

您需要 main 的原因是因为通常您的“主程序”实际上只是另一个模块。入口点位于库提供的启动代码中,该代码是用 C 和汇编的某种组合编写的,而该库代码恰好会调用,main因此您通常需要提供一个。但是直接运行链接器而你没有。

To include a C module1...

包含 C 模块1...

struct MainSub
{
   MainSub()
   {
      // do some stuff
   }
};

MainSub mainSub;

int main(int argc, char *argv[]) { return 0; }



1. And I'm also switching to x86-64 here.1. 我也在这里切换到 x86-64。

回答by Mahesh

Yes it possible to compile with out main but you cannot pass the linking phase though.

是的,可以在没有 main 的情况下进行编译,但您无法通过链接阶段。

#include<stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
  printf(" hello ");
}

回答by eran

"Without using main" might also mean that no logic is allowed within main, but the mainitself exists. I can imagine the question had this cleared out, but since it's not cleared here, this is another possible answer:

“不使用main”也可能意味着 内不允许有逻辑main,但main本身存在。我可以想象这个问题已经解决了,但由于这里没有解决,这是另一个可能的答案:

#import <iostream>

class NoMain
{
public:
    NoMain()
    {
        std::cout << "Hello World!" << std::endl;
        exit(0);
    }
} mainClass;

What will happen here is that the stuff in MainSub's constructor will execute before the unusable mainis executed, and you can place the program's logic there. This of course requires C++, and not C (also not clear from the question).

这里会发生的是,MainSub的构造函数中的内容将在执行 unusable 之前main执行,您可以将程序的逻辑放在那里。这当然需要 C++,而不是 C(从问题中也不清楚)。

回答by eon

I think the macro reference was to renaming the main function, the following is not my code, and demonstrates this. The compiler still sees a main function though, but technically there's no main from a source point of view. I got it here http://www.exforsys.com/forum/c-and-c/96849-without-main-function-how-post412181.html#post412181

我认为宏引用是重命名主函数,以下不是我的代码,并演示了这一点。编译器仍然会看到一个 main 函数,但从技术上讲,从源代码的角度来看,没有 main 函数。我在这里得到它http://www.exforsys.com/forum/c-and-c/96849-without-main-function-how-post412181.html#post412181

g++ nomain.cpp -Wl,-e,_mainClass -v

回答by Joohae Kim

As long as you are using g++ you could change your entry point with linker option -e, so the following code and compile command may let you create a program without a main()function:

只要您使用 g++,您就可以使用链接器选项更改您的入口点-e,因此以下代码和编译命令可以让您创建一个没有main()函数的程序:

##代码##

I gave file name as noname.cpp, and the compile option is:

我给了文件名noname.cpp,编译选项是:

##代码##

To tell the truth, I didn't fully understand why the code can works fine. I suspect that the address of global variable mainClassis the same to constructor of NoMainclass. However, I also have several reasons that I could tell my guess may not correct.

说实话,我并没有完全理解为什么代码可以正常工作。我怀疑全局变量的地址mainClassNoMain类的构造函数相同。但是,我也有几个原因表明我的猜测可能不正确。