• Welcome to Valhalla Legends Archive.
 

Better than recursing on main - for Mephisto

Started by iago, April 26, 2004, 03:15 PM

Previous topic - Next topic

iago

I wrote some code that acts similarely to recursing over main, except without the messy call stack.  It runs on my x86 slackware 9.1 install, and I won't guarentee it'll work anywhere else:

#include <stdio.h>
int i;
int main(int argc, char **argv)
{
   int buffer[argc];

   printf("%d\t", i++);

   if(i < 100)
       buffer[7] -= 5;

   return 0;
}


*grin*

<edit> sample output:
iago@laptop:~/Projects/C$ gcc test.cpp ; a.out
0       1       2       3       4       5       6       7       8       9       10   
11      12      13      14      15      16      17      18      19      20      
21      22      23      24      25      26      27      28      29      30      
31      32      33      34      35      36      37      38      39      40      
41      42      43      44      45      46      47      48      49      50      
51      52      53      54      55      56      57      58      59      60      
61      62      63      64      65      66      67      68      69      70      
71      72      73      74      75      76      77      78      79      80      
81      82      83      84      85      86      87      88      89      90      
91      92      93      94      95      96      97      98   99      iago@laptop:~/Projects/C$
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


MyndFyre

How does this work iago?  Does it reposition the instruction register so that the code points back to the printf instruction?  Because there is no loop...
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Adron

#2
Quote from: iago on April 26, 2004, 03:15 PM
#include <stio.h>
int i;
int main(int argc, char **argv)
{
   int buffer[argc];

   printf("%d\t", i++);

   if(i < 100)
       buffer[7] -= 5;

   return 0;
}


*grin*

#include <stdio.h>

It's interesting code, but I don't quite understand the point of having argc in "buffer[argc]". To be honest, I don't understand how you can pass a variable as the size argument to an auto array. I was expecting a compilation error there, but it compiled just fine. The program runs ok too, but prints rather much on stderr while running.

iago

Now that you mention it, I don't know either.  I used argc simply to confuse the guy at work I was showing it to :)

Myndfyre - it repositions its return address to the "call" instruction.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Mephisto


iago

Quote from: Mephisto on April 26, 2004, 05:54 PM
stdio?  :p

bah, typo.. I deleted some global variables I stopped using and had to retype the include :P
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Arta

#6
Quote from: Adron on April 26, 2004, 04:16 PM
It's interesting code, but I don't quite understand the point of having argc in "buffer[argc]". To be honest, I don't understand how you can pass a variable as the size argument to an auto array. I was expecting a compilation error there, but it compiled just fine. The program runs ok too, but prints rather much on stderr while running.

It does when I compile it (under windows). I don't understand this either!

Mephisto

#7
I thought you could only use a constant value/expression when declaring arrays...At least according to what I was taught you can't use a variable to declare an array in the subscript, because a variables *varies* and the compiler needs to know exactly how much to allocate for the array.

Edit: Apparantly you can declare an array with a variable in the subscript...It makes sense to me too... :p  I never tested it, but should've, so I wrote this very simple program.  ;)


int main() {
   int x = 5;
   int array[x];
   return 0;
}

iago

Quote from: Mephisto on April 27, 2004, 09:13 AM
I thought you could only use a constant value/expression when declaring arrays...
Perhaps argc/argv are special?  I have no idea why it works :)


Here's something else interesting that I noticed:
int main()
{
       main();
       return 0;
}

This will not compile on Linux.  I get the error:
iago@laptop:~/Projects/C$ gcc -Wall test2.cpp
/tmp/cc8BvbGZ.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
iago@laptop:~/Projects/C$
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


iago

#9
Quote from: Mephisto on April 27, 2004, 09:13 AM
I thought you could only use a constant value/expression when declaring arrays...At least according to what I was taught you can't use a variable to declare an array in the subscript, because a variables *varies* and the compiler needs to know exactly how much to allocate for the array.

Edit: Apparantly you can declare an array with a variable in the subscript...It makes sense to me too... :p  I never tested it, but should've, so I wrote this very simple program.  ;)


int main() {
   int x = 5;
   int array[x];
   return 0;
}


Did you try running that with warnings?

I get this:
iago@laptop:~/Projects/C$ gcc -Wall test2.cpp
test2.cpp: In function `int main()':
test2.cpp:4: warning: unused variable `int array[((x - 1) + 1)]'
iago@laptop:~/Projects/C$


it declares that variable "array" very weirdly :/

<edit>
I tried it on c, not c++, and it still works
iago@laptop:~/Projects/C$ gcc -Wall test.c
test.c: In function `main':
test.c:4: warning: unused variable `array'
iago@laptop:~/Projects/C$


Ouch, my brain :(
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


iago

In case somebody's curious, this program:

#include <stdio.h>

int main()
{
       int x;

       printf("What is the value of x?\n");
       scanf("%d", &x);

       int array[x];

       for(int i = 0; i < x; i++)
       {
               array[i] = 0;
       }

       return 0;
}


compiles fine, on Linux, and produces the main function:

main:
.LFB1:
       pushl   %ebp
.LCFI0:
       movl    %esp, %ebp
.LCFI1:
       subl    $24, %esp
.LCFI2:
       andl    $-16, %esp
       movl    $0, %eax
       subl    %eax, %esp
       movl    %esp, -12(%ebp)
       subl    $12, %esp
       pushl   $.LC0
.LCFI3:
       call    printf
       addl    $16, %esp
       subl    $8, %esp
       leal    -4(%ebp), %eax
       pushl   %eax
       pushl   $.LC1
       call    scanf
       addl    $16, %esp
       movl    -4(%ebp), %eax
       decl    %eax
       sall    $2, %eax
       addl    $4, %eax
       addl    $15, %eax
       shrl    $4, %eax
       sall    $4, %eax
       subl    %eax, %esp
       movl    %esp, -16(%ebp)
       movl    $0, -8(%ebp)
.L2:
       movl    -8(%ebp), %eax
       cmpl    -4(%ebp), %eax
       jl      .L5
       jmp     .L3
.L5:
       movl    -8(%ebp), %eax
       movl    -16(%ebp), %edx
       movl    $0, (%edx,%eax,4)
       leal    -8(%ebp), %eax
       incl    (%eax)
       jmp     .L2
.L3:
       movl    -12(%ebp), %esp
       movl    $0, %eax
       leave
       ret


I don't have time right now to figure out how this is working, but feel free :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Yoni

#11
Btw, has anyone tried compiling with ANSI-compliance enabled?
I'm pretty sure this is a GCC extension.
Edit: I checked (Comeau) and it's standard C99. Interesting...

As for how it works...

Quote from: iago on April 27, 2004, 09:28 AM
       subl    %eax, %esp


iago

#12
Quote from: Yoni on April 27, 2004, 10:10 AM
Btw, has anyone tried compiling with ANSI-compliance enabled?
I'm pretty sure this is a GCC extension.
Edit: I checked (Comeau) and it's standard C99. Interesting...

As for how it works...

Quote from: iago on April 27, 2004, 09:28 AM
       subl    %eax, %esp


Wow,that's smart, it subtracts the variable from esp :)  *impressed*

iago@laptop:~/Projects/C$ gcc -ansi -fno-nonansi-builtins -Wall test2.cpp
iago@laptop:~/Projects/C$


works fine :)

<edit> I think -ansi means standard C89.

I had no idea this was allowed. hmm.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Arta

Well, I copied your code straight over:


error C2466: cannot allocate an array of constant size 0
error C2057: expected constant expression
error C2133: 'buffer' : unknown size


Although I think I see how it works now.. Kind've intentionally overflowing the stack - clever :)

iago

Quote from: Arta[vL] on April 27, 2004, 02:21 PM
Well, I copied your code straight over:


error C2466: cannot allocate an array of constant size 0
error C2057: expected constant expression
error C2133: 'buffer' : unknown size


Although I think I see how it works now.. Kind've intentionally overflowing the stack - clever :)

Try making my array a constant size of "1"
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*