Author | Message | Time |
---|---|---|
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: [code]#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; } [/code] *grin* <edit> sample output: [code]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$ [/code] | April 26, 2004, 8:15 PM |
Myndfyr | 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... | April 26, 2004, 9:02 PM |
Adron | [quote author=iago link=board=30;threadid=6491;start=0#msg57034 date=1083010559] [code]#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; } [/code] *grin* [/quote] [code]#include <stdio.h>[/code] 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. | April 26, 2004, 9:16 PM |
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. | April 26, 2004, 9:27 PM |
Mephisto | stdio? :p | April 26, 2004, 10:54 PM |
iago | [quote author=Mephisto link=board=30;threadid=6491;start=0#msg57045 date=1083020054] stdio? :p [/quote] bah, typo.. I deleted some global variables I stopped using and had to retype the include :P | April 26, 2004, 10:59 PM |
Arta | [quote author=Adron link=board=30;threadid=6491;start=0#msg57042 date=1083014191] 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. [/quote] It does when I compile it (under windows). I don't understand this either! | April 27, 2004, 1:36 PM |
Mephisto | 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. ;) [code] int main() { int x = 5; int array[x]; return 0; }[/code] | April 27, 2004, 2:13 PM |
iago | [quote author=Mephisto link=board=30;threadid=6491;start=0#msg57089 date=1083075199] I thought you could only use a constant value/expression when declaring arrays... [/quote] Perhaps argc/argv are special? I have no idea why it works :) Here's something else interesting that I noticed: [code]int main() { main(); return 0; } [/code] This will not compile on Linux. I get the error: [code]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$[/code] | April 27, 2004, 2:18 PM |
iago | [quote author=Mephisto link=board=30;threadid=6491;start=0#msg57089 date=1083075199] 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. ;) [code] int main() { int x = 5; int array[x]; return 0; }[/code] [/quote] Did you try running that with warnings? I get this: [code]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$[/code] it declares that variable "array" very weirdly :/ <edit> I tried it on c, not c++, and it still works [code]iago@laptop:~/Projects/C$ gcc -Wall test.c test.c: In function `main': test.c:4: warning: unused variable `array' iago@laptop:~/Projects/C$[/code] Ouch, my brain :( | April 27, 2004, 2:20 PM |
iago | In case somebody's curious, this program: [code]#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; } [/code] compiles fine, on Linux, and produces the main function: [code]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 [/code] I don't have time right now to figure out how this is working, but feel free :) | April 27, 2004, 2:28 PM |
Yoni | 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 author=iago link=board=30;threadid=6491;start=0#msg57095 date=1083076103] [code] subl %eax, %esp [/code] [/quote] | April 27, 2004, 3:10 PM |
iago | [quote author=Yoni link=board=30;threadid=6491;start=0#msg57101 date=1083078640] 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 author=iago link=board=30;threadid=6491;start=0#msg57095 date=1083076103] [code] subl %eax, %esp [/code] [/quote] [/quote] Wow,that's smart, it subtracts the variable from esp :) *impressed* [code]iago@laptop:~/Projects/C$ gcc -ansi -fno-nonansi-builtins -Wall test2.cpp iago@laptop:~/Projects/C$[/code] works fine :) <edit> I think -ansi means standard C89. I had no idea this was allowed. hmm. | April 27, 2004, 3:26 PM |
Arta | Well, I copied your code straight over: [code] error C2466: cannot allocate an array of constant size 0 error C2057: expected constant expression error C2133: 'buffer' : unknown size [/code] Although I think I see how it works now.. Kind've intentionally overflowing the stack - clever :) | April 27, 2004, 7:21 PM |
iago | [quote author=Arta[vL] link=board=30;threadid=6491;start=0#msg57119 date=1083093675] Well, I copied your code straight over: [code] error C2466: cannot allocate an array of constant size 0 error C2057: expected constant expression error C2133: 'buffer' : unknown size [/code] Although I think I see how it works now.. Kind've intentionally overflowing the stack - clever :) [/quote] Try making my array a constant size of "1" | April 27, 2004, 8:22 PM |
Mephisto | Arta, do you get that error when you try to declare an array with a non-constant value/expression? | April 27, 2004, 9:02 PM |
kamakazie | [quote author=iago link=board=30;threadid=6491;start=0#msg57092 date=1083075492] [quote author=Mephisto link=board=30;threadid=6491;start=0#msg57089 date=1083075199] I thought you could only use a constant value/expression when declaring arrays... [/quote] Perhaps argc/argv are special? I have no idea why it works :) Here's something else interesting that I noticed: [code]int main() { main(); return 0; } [/code] This will not compile on Linux. I get the error: [code]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$[/code] [/quote] gcc doesn't like *.cpp files. You need to use g++ or rename test2.cpp to test2.c. | April 27, 2004, 11:15 PM |
Myndfyr | [quote author=Mephisto link=board=30;threadid=6491;start=15#msg57137 date=1083099734] Arta, do you get that error when you try to declare an array with a non-constant value/expression? [/quote] I'm somewhat confused (perhaps due to my C newbletness), but I was under the impression that you *could* create variable-size arrays. Vis-a-vis: [code] int main() { cout << "Enter a value:" << endl; int num = 0; cin >> num; int *array = malloc(num * sizeof(int)); if (array == NULL) return 1; //... } [/code] and then you would effectively have an array with the size that you wanted. I can't remember if it can be cast or not... It seems like it should be able to, by setting an array pointer to the variable of the array itself. Like I said though, I'm a C newblet, so I could be off. | April 27, 2004, 11:55 PM |
K | C99 says you can do this: [code] int x = 10; int Foo[x]; [/code] you could do it like so: [code] int x = 10; int *Foo = malloc(x * sizeof(int)); // ... free(Foo); [/code] the difference is primarily that you have to free() the second, and where they are allocated. | April 28, 2004, 12:36 AM |
iago | [quote author=K link=board=30;threadid=6491;start=15#msg57194 date=1083112568] C99 says you can do this: [code] int x = 10; int Foo[x]; [/code] you could do it like so: [code] int x = 10; int *Foo = malloc(x * sizeof(int)); // ... free(Foo); [/code] the difference is primarily that you have to free() the second, and where they are allocated. [/quote] Also, you can return the second, it's on the heap, but you can't return the first one, it's on the stack and will get broken. | April 28, 2004, 1:02 AM |
Arta | [quote author=Mephisto link=board=30;threadid=6491;start=15#msg57137 date=1083099734] Arta, do you get that error when you try to declare an array with a non-constant value/expression? [/quote] Looks that way, yes. I get the same errors with: [code] int main(int argc, char **argv) { int x = 10; int y[x]; return 0; } [/code] Perhaps there's a compiler option somewhere that controls this? Edit: perhaps not - see ms-help://MS.VSCC/MS.MSDNVS/vccore/html/C2057.htm: [quote] expected constant expression The context requires a constant expression. The following sample generates C2057: // C2057.cpp int i; // use the line below to resolve the error // const int i = 8; int b[i]; // C2057 int main() { } [/quote] | April 28, 2004, 11:15 PM |
Mephisto | That's what I thought. I could've sworn you could never use a non-constant value when declaring your array, though I don't see why you couldn't, it will always know how much memory to allocate. Perhaps some compilers now violate this? Or the standards have changed...? | April 28, 2004, 11:37 PM |