Author Topic: C++ program without main function  (Read 6556 times)

0 Members and 2 Guests are viewing this topic.

Offline parad0x

  • VIP
  • Royal Highness
  • *
  • Posts: 638
  • Cookies: 118
    • View Profile
C++ program without main function
« on: December 09, 2012, 10:55:59 am »
I was thinking to write a c++ program without a function naming main(),but when I googled it,I saw that they have just renamed it so n00bs think that it is a program without main() function.Is there absolutely no way to write a c++ program without the function main()? ??? ???
Some of them include:
Example 1:
Code: (C++) [Select]
#include <iostream.h>
#define hello() main()
int hello()
{
cout<<"Hello";
return 0;
}
Example 2:
Code: (C++) [Select]
#include <iostream.h>
#define tutorial(s,t,u,m,p,e,d) m##s##u##t
#define hello tutorial(a,n,i,m,a,t,e)
int hello()
{
cout<<"Hello";
return 0;
}
This is basically renaming the function main.Is there any other method in which do not rename but can code without the function main()? :P

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: C++ program without main function
« Reply #1 on: December 09, 2012, 04:51:36 pm »
Eh not exactly.  You have to either have a int main() or a void _start().  however, the later is rather tricky to get right and requires mucking around with assembly a lot.
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: C++ program without main function
« Reply #2 on: December 09, 2012, 05:01:38 pm »
You can change the entry point, but it could cause problems. For example, under linux the entry point is not your main function, but a initializer function which later calls your main ().

Offline Live Wire

  • Knight
  • **
  • Posts: 189
  • Cookies: 4
  • Up on your Net
    • View Profile
Re: C++ program without main function
« Reply #3 on: December 09, 2012, 06:21:16 pm »
What would the point of this experiment be? or is this just to see if it can be done. I'm no expert at c++, but i cant think of why i wouldn't want a main(), unless this is just for experimentation.
"There is no right or wrong, there is only fun and boring."

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: C++ program without main function
« Reply #4 on: December 09, 2012, 11:43:48 pm »
What would the point of this experiment be? or is this just to see if it can be done. I'm no expert at c++, but i cant think of why i wouldn't want a main(), unless this is just for experimentation.

You bypass crt0 which may include some stuff you don't want like it may set up memory in a way you don't want or something obscure like that.  For 99% of the stuff you'll want to do there isn't a useful thing about it other than to look cool.
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline Live Wire

  • Knight
  • **
  • Posts: 189
  • Cookies: 4
  • Up on your Net
    • View Profile
Re: C++ program without main function
« Reply #5 on: December 10, 2012, 08:00:26 am »
You bypass crt0 which may include some stuff you don't want like it may set up memory in a way you don't want or something obscure like that.

ah, i got ya. couldnt you just respecify where you want your variables stored, then?
"There is no right or wrong, there is only fun and boring."

Offline xzid

  • Knight
  • **
  • Posts: 329
  • Cookies: 41
    • View Profile
Re: C++ program without main function
« Reply #6 on: December 10, 2012, 09:48:51 am »
If you exclude libc, you can make function void_start.

didn't read thread.

edit:
Code: (c) [Select]
void _start() {
        asm("push $0; mov $1, %eax; int $0x80");
}

Code: (bash) [Select]
gcc -nostdlib -o _start _start.c
freebsd/x86
« Last Edit: December 10, 2012, 09:55:45 am by xzid »

Offline parad0x

  • VIP
  • Royal Highness
  • *
  • Posts: 638
  • Cookies: 118
    • View Profile
Re: C++ program without main function
« Reply #7 on: December 10, 2012, 12:40:02 pm »
What would the point of this experiment be? or is this just to see if it can be done. I'm no expert at c++, but i cant think of why i wouldn't want a main(), unless this is just for experimentation.
I'm having a bet on this topic.I had asked this question to about 30 students who are having C++ in CS as their main subject and they bet me that such a program can't exist. 8)

Offline bluechill

  • Cybermancer
  • Royal Highness
  • ****
  • Posts: 682
  • Cookies: 344
  • I am the existence in these walls
    • View Profile
Re: C++ program without main function
« Reply #8 on: December 10, 2012, 02:19:44 pm »
If you exclude libc, you can make function void_start.

didn't read thread.

edit:
Code: (c) [Select]
void _start() {
        asm("push $0; mov $1, %eax; int $0x80");
}

Code: (bash) [Select]
gcc -nostdlib -o _start _start.c
freebsd/x86

That's not true.  libc does not contain crt0.o.  You can link with libc if you desire.  Just make sure you don't link with the standard libraries.  There is a difference. -nostdlib links without libc, libstdc++, crt0.o etc.  But you can still link in libc manually and have it work.
I have dreamed a dream, but now that dream has gone from me.  In its place now exists my own reality, a reality which I have created for myself by myself.

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: C++ program without main function
« Reply #9 on: December 11, 2012, 06:56:21 pm »
Couple quick things...

First; 'main()' is, as defined by the C standard, the function called at program startup.  This does NOT mean that it is the program entry point.  The program entry point is '_start()'(on POSIX systems).  The 'main()' function should never be the program entry point.

How it works(over-simplification): the program is loaded into memory, the execution environment is set up, the process is forked off and we jmp to the program entry point.  The program entry point, typically '_start()', is responsible for setting up program arguments and generally beginning the execution of the process.  Usually '_star()' will call 'main()' but this is not mandatory.  Granted, it violates the c99 standard not to call 'main()' but at this point we really don't care about standards.

The point:
IF you want to create a program without 'main()', you are free to do so.  You need only substitute the system implemented program entry point('_start()' on POSIX systems) for one of your own making.  On Linux, crt0.o contains the C implementation and crt1.o contains the C++ implementation.

You can still link with your standard libraries.  Linker option -e lets you replace the entry point(_start()).  You can replace it with pretty much whatever you desire.  You can call the option from gcc with -Wl.  You can even create your new '_start()' replacement to send your 'main()'(replacement) different arguments(like Windows does for 'WinMain()').

So, @Mr. Perfect; you can, in fact, replace the 'main()' function with another function of a different name.  You technically can even replace '_start()' with a differently named function since you can specify the program entry point.  In theory, this could even let you do useful things like set up different entry points for different platforms and make a program far, far more cross-platform.

Anywho..basic '_start()' code for PPC(stolen from somewhere for nefarious purposes):
Code: (asm) [Select]
/*
 * crt0.S -- startup file for PowerPC systems.
 *
 */

    .text
    .globl  _start
    .type   _start,@function
_start:
#if 1
    /* load the system stack */
    lis %r1, __USER_STACK_TOP@ha
    la  %r1, __USER_STACK_TOP@l(%r1)
#endif

    /* initialize data sections */
    bl  clear_table
    bl  copy_table

    /* initialize interrupts */

    bl  Mpc52xxInitInterrupts

    li  %r3,0       /* argc = 0 */

    li  %r4,0       /* argv = NULL */
    /* Let her rip */
    bl  main

    /* return value from main is argument to exit */
    bl  exit
.Lstart:
    .size   _start,.Lstart-_start

    .extern atexit
    .globl  __atexit
    .section ".sdata","aw"
    .align  2
__atexit:           /* tell C's eabi-ctor's we have an atexit function */
    .long   atexit@fixup    /* and that it is to register __do_global_dtors */

    .section ".fixup","aw"
    .align  2
    .long   __atexit

    .section    ".text"
    .align 2
    .globl clear_table
    .type    clear_table,@function

clear_table:
    lis %r9,__clear_table@ha
    la  %r9,__clear_table@l(%r9)
    lwz %r0,4(%r9)
    cmpwi   %r0,-1
    beqlr
clear_loop1:
    lwz %r0,4(%r9)
    addi    %r11,%r9,8
    srwi.   %r10,%r0,2
    lwz %r9,0(%r9)
    mtctr   %r10
    beq clear_loop3
    li  %r0,0
clear_loop2:
    stw %r0,0(%r9)
    addi    %r9,%r9,4
    bdnz    clear_loop2
clear_loop3:
    mr  %r9,%r11
    lwz %r0,4(%r9)
    cmpwi   %r0,-1
    bne clear_loop1
    blr

clear_table_end:
    .size    clear_table,clear_table_end-clear_table
    .align 2

    .globl copy_table
    .type    copy_table,@function
copy_table:
    lis %r9,__copy_table@ha
    la  %r9,__copy_table@l(%r9)
    lwz %r0,8(%r9)
    cmpwi   %r0,-1
    beqlr
copy_loop1:
    lwz %r0,8(%r9)
    addi    %r10,%r9,12
    srwi.   %r11,%r0,2
    mtctr   %r11
    lwz %r11,0(%r9)
    lwz %r9,4(%r9)
    beq copy_loop3
copy_loop2:
    lwz %r0,0(%r11)
    addi    %r11,%r11,4
    stw %r0,0(%r9)

    addi    %r9,%r9,4
    bdnz    copy_loop2
copy_loop3:
    mr  %r9,%r10
    lwz %r0,8(%r9)
    cmpwi   %r0,-1
    bne copy_loop1
    blr
copy_table_end:
    .size    copy_table,copy_table_end-copy_table
-Xires