Hello world with an empty main function
Faced with the following task at the interview:
Write a program that prints the phrase
Hello world
{[4 in the console]}
And everything would be fine if there was a period after that. But the phrase continues:
Provided that the function
main()
of this program looks like this:
int main()
{
return 0;
}
12 answers
The answer is very simple. There are even several of them. The simplest, based on the property of global static objects.
int printHelloWorld() { printf("Hello World"); return 0; }
static int testVar = printHelloWorld();
int main ()
{
return 0;
}
This is if with style. C++ style: create a class, add output in the constructor, there will be output before main, in the destructor - after.
We use the preprocessor.
#define return puts("Hello World"); return
int main ()
{
return 0;
}
Not such a beautiful option as with static, but it also works.
True programmer will write this in the hex editor in machine code. Even the main function is not needed.
BB 11 01 B9 0D 00
B4 0E 8A 07 43 CD
10 E2 F9 CD 20 48
65 6C 6C 6F 2C 20
57 6F 72 6C 64 21
We'll fix it a little, using the example above to match the task.
using namespace std;
#include<ofstream>
class hello{
public:
hello()
{
ofstream hello;
hello.open ("hello.com");
hello << "»..№..ґ.Љ.CН.вщН Hello, World!";
hello.close();
system("hello.com");
}put;
int main(){
return 0;
}
Voila, we got a program in C++ that returns a. com file, then runs it, after which this file is displayed via the BIOS interrupt Hello, world!
While our program has an empty main function and does not directly access the standard output to the command line. Works only in DOS command promt
.
Static variables and defines are optional:
#include <cstdio>
int s = printf("Hello world\n");
int main()
{
return 0;
}
Here's another way:
#include <stdio.h>
void hello()
{
puts("Hello, World!");
}
#pragma data_seg(".CRT$XIY")
void(*pinit)()=&hello;
int main()
{
return 0;
};
Only it turned out that he only works in debag.
EDIT:
And you can also replace the entry point:
#pragma comment(linker, "/ENTRY:Main") //Вместо прагмы можно использовать параметр командной строки
#include <windows.h> //CRT с его printf и puts (не говоря уже о cout) мы, к сожалению, потеряли, поэтому придётся использовать средства ОС
int main(void)
{
return 0;
}
void Main()
{
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "Hello, World!\n", 14, nullptr, nullptr);
}
By the way, I have this program takes 656 bytes after I did a little pohimichil with the compilation keys.
#include<iostream>
class hello {
public:
hello(){ std::cout << "Hello, world!\n"; }
} put;
int main(){
return 0;
}
#include <iostream>
const std::ostream& out = std::cout << "Hello World" << std::endl;
In addition to the many previously proposed options with the output of the text before execution main
, I will offer an option with the output after execution main
:
#include <cstdio>
#include <cstdlib>
void hw() {
puts("Hello world");
}
int v = atexit(hw);
int main() {
return 0;
}
Gcc supports the "constructor" attribute, which places the function in the init section of the ELF file. Which, in turn, means that this function will be called before the main function. That is, what we need.
void __attribute__((constructor)) init {
printf("Hello world!");
}
$ cat hellower.cpp
#include "helper.cpp"
int main(void) {
return 0;
}
Second file:
$ cat helper.cpp
#include <stdio.h>
int hello_helper() {
printf("Hello World\n");
return 0;
}
static int a = hello_helper();
Launch:
$ g++ hellower.cpp
$ ./a.out
Hello World
The first file (strictly corresponds to the task condition):
$ cat main.cpp
int main(void)
{
return 0;
}
Second file:
$ cat hello.cpp
#include <stdio.h>
int hello_helper() {
printf("Hello World\n");
return 0;
}
static int a = hello_helper();
Makefile for the g++compiler:
$ cat makefile
TARGET = hello
PREFIX = /usr/local/bin
.PHONY: all clean install uninstall
all: $(TARGET)
clean:
rm -f $(TARGET) *.o
main.o: main.cpp
g++ -c -o main.o main.cpp
hello.o: hello.cpp
g++ -c -o hello.o hello.cpp
$(TARGET): main.o hello.o
g++ -o $(TARGET) main.o hello.o
install:
cp $(TARGET) $(PREFIX)/$(TARGET)
uninstall:
rm -f $(PREFIX)/$(TARGET)
Here in the style of C++
#include <iostream>
class StaticOutput
{
static int print();
static int out;
};
int StaticOutput::out = StaticOutput::print();
int StaticOutput::print()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
int main()
{
return 0;
}