Page 2 of 2

Posted: Mon Nov 12, 2007 8:28 am
by JamesM
Craze Frog wrote:
MessiahAndrw wrote:
Craze Frog wrote:main() has a special meaning in C. Just rename your function k_main() or something and the warning will go away.
No it doesn't. main() is no different to any other function. It is usually the first C/C++ function called in your code, but you can easily edit your assembly stub to change that.
No, main has a special meaning. It means, "this is where I want the program execution to start". Just read the C99 standard, section 5.1.2.2.1. The same standard also prohibits any function named main to have any other return type than int. Which is the reason for the warning in GCC.

Edit: JamesM got there before me, but unfortunately he isn't completely correct either.
In implementation main() is no different...
Source code:

Code: Select all

int crudebox() {
    __asm__("#CODE START 2");
    __asm__("#CODE END 2");
    return 0;
}

int main() {
    __asm__("#CODE START");
    __asm__("#CODE END");
    return 0;
}
Asm generated by gcc 3.4.4 for cygwin:

Code: Select all

...
_crudebox:
	pushl	%ebp
	movl	%esp, %ebp
/APP
	#CODE START 2
	#CODE END 2
/NO_APP
	popl	%ebp
	xorl	%eax, %eax
	ret
...
_main:
	pushl	%ebp
	movl	$16, %eax
	movl	%esp, %ebp
	subl	$8, %esp
	andl	$-16, %esp
	call	__alloca
	call	___main
/APP
	#CODE START
	#CODE END
/NO_APP
	leave
	xorl	%eax, %eax
	ret
I agree that it shouldn't be like that, the stack probing should be done in another function that calls main, but someone decided to do it like that.
Hrmm, just did that test myself, it seems to do some stack alignment.

Code: Select all

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

int func(char argc, char **argv)
{
    return 0;
}

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

$ gcc -o test.o test.c -nostdlib

$ objdump -d test.o

test.o:     file format elf32-i386

Disassembly of section .text:

08048094 <func>:
 8048094:       55                      push   %ebp
 8048095:       89 e5                   mov    %esp,%ebp
 8048097:       83 ec 04                sub    $0x4,%esp
 804809a:       8b 45 08                mov    0x8(%ebp),%eax
 804809d:       88 45 fc                mov    %al,0xfffffffc(%ebp)
 80480a0:       b8 00 00 00 00          mov    $0x0,%eax
 80480a5:       c9                      leave
 80480a6:       c3                      ret

080480a7 <main>:
 80480a7:       8d 4c 24 04             lea    0x4(%esp),%ecx
 80480ab:       83 e4 f0                and    $0xfffffff0,%esp
 80480ae:       ff 71 fc                pushl  0xfffffffc(%ecx)
 80480b1:       55                      push   %ebp
 80480b2:       89 e5                   mov    %esp,%ebp
 80480b4:       51                      push   %ecx
 80480b5:       83 ec 04                sub    $0x4,%esp
 80480b8:       8b 01                   mov    (%ecx),%eax
 80480ba:       88 45 f8                mov    %al,0xfffffff8(%ebp)
 80480bd:       b8 00 00 00 00          mov    $0x0,%eax
 80480c2:       83 c4 04                add    $0x4,%esp
 80480c5:       59                      pop    %ecx
 80480c6:       5d                      pop    %ebp
 80480c7:       8d 61 fc                lea    0xfffffffc(%ecx),%esp
 80480ca:       c3                      ret
Tres etrange.

Posted: Tue Nov 13, 2007 1:48 am
by pcmattman
No, main has a special meaning. It means, "this is where I want the program execution to start". Just read the C99 standard, section 5.1.2.2.1. The same standard also prohibits any function named main to have any other return type than int. Which is the reason for the warning in GCC.
It only has a special meaning in the context of the standards... It has nothing to do with C itself, it is just a function. If I wanted to I could make the entry point to my OS's apps "prog_entrypoint" but that would defeat the purpose of my compatibility layer for *nix systems.

Posted: Tue Nov 13, 2007 2:49 am
by Solar
pcmattman wrote:It only has a special meaning in the context of the standards... It has nothing to do with C itself, it is just a function.
I don't really get your meaning here. The language C is defined by a standard (ISO/IEC 9899), which defines the function main() as having a special meaning:
ISO/IEC 9899:1999 wrote:5.1.2.2.1 Program startup
1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

Code: Select all

int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

Code: Select all

int main(int argc, char *argv[]) { /* ... */ }
or equivalent;9) or in some other implementation-defined manner.

9) Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.
If you violate this constraint, the compiler will give you a warning, as it would with any function for which declaration and definition differ. (In this case, main() is declared implicitly by the standard.)

The correct sollution here, of course, is to compile your kernel as "-ffreestanding", as main() only has this special meaning in a hosted environment.

Posted: Tue Nov 13, 2007 2:52 am
by pcmattman
Solar wrote:The correct sollution here, of course, is to compile your kernel as "-ffreestanding", as main() only has this special meaning in a hosted environment.
Hosted is the word I was looking for there, not standards... Couldn't for the life of me remember that :(