473,387 Members | 1,700 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Casting main() not allowed?

Have a look at this

#include <stdio.h>
#include <string.h>
int track = 0;
char this[10] = "why ";
char that[10] = "not?";
int main(void)
{
track++;
if (track < 5)
main();
if (track == 5)
{
strcat(this,(char *)main());
printf("%s\n", this);
}
if (track == 6)
{
track = 7;
return (int)that;
}
if (track == 7) return 0;
return 0;
}

I'm not really sure what my question is, but I'm quite suprised it
works.
Any other ridiculous things you can do with a recursive main?

Matt

Apr 25 '06 #1
13 1803
ballpointpenthief wrote:
Have a look at this

#include <stdio.h>
#include <string.h>
int track = 0;
char this[10] = "why ";
char that[10] = "not?";
int main(void)
{
track++;
if (track < 5)
main();
if (track == 5)
{
strcat(this,(char *)main());
printf("%s\n", this);
}
if (track == 6)
{
track = 7;
return (int)that;
}
if (track == 7) return 0;
return 0;
}

I'm not really sure what my question is, but I'm quite suprised it
works.
Any other ridiculous things you can do with a recursive main?

Matt

That looks like it's good with any recursive function. main() is no
different than any other function, except that its first caller is the OS.
Apr 25 '06 #2
"ballpointpenthief" <Ma*************@gmail.com> writes:
Have a look at this
[...] int main(void)
{ [...] strcat(this,(char *)main()); [...] return 0;
}

I'm not really sure what my question is, but I'm quite suprised it
works.
What do you mean when you say it "works"?

main is a function that returns an int. You've declared it so it
takes no arguments, so main() is a valid call; since the only value it
returns is 0, the expression main() evaluates to the int value 0.

You then cast this value to type char*. This is allowed, but
non-portable; the result of converting an integer to a pointer is
implementation-defined. Converting an integer *constant* 0 to a
pointer type yields a null pointer. Converting a non-constant integer
expression with a value of 0 to a pointer type is very likely to yield
a null pointer, but it's not required to (though there's some
disagreement on this point).

So, you're calling strcat() with what is most likely null pointer as
its second argument. The result is undefined behavior, which is a
common result of using pointer casts without being *very* careful.
Casting typically tells the compiler to shut up and stop complaining,
so the lack of a warning message (assuming you didn't get one) isn't
surprising.
Any other ridiculous things you can do with a recursive
main?


There are infinitely many bad C programs that can be written. Alas,
too many of them actually exist; I'm afraid I don't have time to
enumerate all the others.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 25 '06 #3

Keith Thompson wrote:
You then cast this value to type char*. This is allowed, but
non-portable; the result of converting an integer to a pointer is
implementation-defined. So, you're calling strcat() with what is most likely null pointer as
its second argument. The result is undefined behavior....

<snip>

I think you must have skimmed the line...
return (int)that;
Where I am returning a pointer converted to an integer. (Although I'm
not sure whether this would neccesarily fit in an int.)
Is that portable?

Apr 25 '06 #4
In article <11*********************@j33g2000cwa.googlegroups. com>,
ballpointpenthief <Ma*************@gmail.com> wrote:
I think you must have skimmed the line...
return (int)that;
Where I am returning a pointer converted to an integer. (Although I'm
not sure whether this would neccesarily fit in an int.)
Is that portable?


No.

It will typically work if int is "big enough" (which it often isn't on
modern systems), but even that is not guaranteed.

C99 provides an intptr_t integer type through which pointers can be
passed, but unfortunately it's optional.

-- Richard
Apr 26 '06 #5
ballpointpenthief wrote:
Have a look at this

#include <stdio.h>
#include <string.h>
int track = 0;
char this[10] = "why ";
char that[10] = "not?";
int main(void)
{
track++;
if (track < 5)
main();
if (track == 5)
{
strcat(this,(char *)main());
This will work assuming that the int value is a valid int representation
of a pointer.
printf("%s\n", this);
}
if (track == 6)
{
track = 7;
return (int)that;
This will work provided that the pointer converted to an int actually
fits. For a while, this has been the case on most popular
implementations, but with 64 bit systems this is quite likely not to
work. Pointers are 64 bits but ints are only 32 bits, so what do you
think will happen to the other 32 bits?
}
if (track == 7) return 0;
return 0;
}

I'm not really sure what my question is, but I'm quite suprised it
works.
Keep trying other systems and you will find conforming implementations
where it does not work.
Any other ridiculous things you can do with a recursive main?


Lots, However, I would not recommend any of them. The real challenge is
to find a sensible use for calling main recursively!
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Apr 26 '06 #6
"ballpointpenthief" <Ma*************@gmail.com> writes:
Keith Thompson wrote:
You then cast this value to type char*. This is allowed, but
non-portable; the result of converting an integer to a pointer is
implementation-defined.

So, you're calling strcat() with what is most likely null pointer as
its second argument. The result is undefined behavior....

<snip>

I think you must have skimmed the line...
return (int)that;
Where I am returning a pointer converted to an integer. (Although I'm
not sure whether this would neccesarily fit in an int.)
Is that portable?


Yes, I did miss that line. I also didn't take the time figure out the
program's control flow.

C99 6.3.2.3 p5-6:

An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined, might
not be correctly aligned, might not point to an entity of the
referenced type, and might be a trap representation.

Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior is
undefined. The result need not be in the range of values of any
integer type.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 26 '06 #7
Richard Tobin wrote:
...
C99 provides an intptr_t integer type through which pointers can be
passed, but unfortunately it's optional.


Why 'unfortunately'? I have to wonder why it exists at all in C99!

--
Peter

Apr 26 '06 #8
"ballpointpenthief" <Ma*************@gmail.com> wrote:
Keith Thompson wrote:
You then cast this value to type char*. This is allowed, but
non-portable; the result of converting an integer to a pointer is
implementation-defined.

So, you're calling strcat() with what is most likely null pointer as
its second argument. The result is undefined behavior....

<snip>

I think you must have skimmed the line...
return (int)that;
Where I am returning a pointer converted to an integer. (Although I'm
not sure whether this would neccesarily fit in an int.)
Is that portable?


Not only is it not portable, it is a very silly idea. Why on earth would
you want to torture main() so? What has it ever done to you?

Richard
Apr 26 '06 #9

Flash Gordon wrote:
ballpointpenthief wrote:


<snip>
Any other ridiculous things you can do with a recursive main?


Lots, However, I would not recommend any of them. The real challenge is
to find a sensible use for calling main recursively!


I was once writing a bytecode interpreter, where one of the legal
commands meant 'replace the currently running program with this string,
and run the string as if it were a program, with the command-line
arguments shifted left.' I implemented this with a static variable
holding the program, and when this command was reached it copied the
string into the program, and then executed something like
return main(argc-1, argv+1);
Of course, this could just be replaced by a loop, but it was not a
command that was frequently run (except by a bootstrap that always ran)
and I didn't want to special-case it in the startup code. (The static
variable initially held the bootstrap, and the bootstrap loaded the
file in argv[1] and ran it with that command. As a result, argv[1]
shifted onto argv[0] as a bonus, as it gave the filename of the program
now running). For a compiler that optimizes tail-recursion, this isn't
even very inefficient (a function calling itself in a 'return'
statement must be a good candidate for tail-recursion elimination!).

Apr 26 '06 #10
ais523 wrote:
Flash Gordon wrote:
ballpointpenthief wrote:


<snip>
Any other ridiculous things you can do with a recursive main?

Lots, However, I would not recommend any of them. The real challenge is
to find a sensible use for calling main recursively!


I was once writing a bytecode interpreter, where one of the legal
commands meant 'replace the currently running program with this string,


<snip>

You spoilt the challenge for the OP! I didn't say one couldn't find a
sensible use for it, just indicated it was a challenge.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Apr 26 '06 #11

Flash Gordon wrote:
ais523 wrote:
Flash Gordon wrote:
ballpointpenthief wrote:


<snip>
Any other ridiculous things you can do with a recursive main?
Lots, However, I would not recommend any of them. The real challenge is
to find a sensible use for calling main recursively!


I was once writing a bytecode interpreter, where one of the legal
commands meant 'replace the currently running program with this string,


<snip>

You spoilt the challenge for the OP! I didn't say one couldn't find a
sensible use for it, just indicated it was a challenge.


I'm not entirely sure whether that last post was meant to be serious or
not. If it was, I apologize. If the challenge was intended purely for
the OP and you had stated so, I of course would not have tried to
answer it here.

Apr 26 '06 #12
ais523 wrote:
Flash Gordon wrote:
ais523 wrote:
Flash Gordon wrote:

ballpointpenthief wrote:
<snip>

> Any other ridiculous things you can do with a recursive main?
Lots, However, I would not recommend any of them. The real challenge is
to find a sensible use for calling main recursively!
I was once writing a bytecode interpreter, where one of the legal
commands meant 'replace the currently running program with this string,

<snip>

You spoilt the challenge for the OP! I didn't say one couldn't find a
sensible use for it, just indicated it was a challenge.


I'm not entirely sure whether that last post was meant to be serious or
not. If it was, I apologize. If the challenge was intended purely for
the OP and you had stated so, I of course would not have tried to
answer it here.


Nothing to apologise for, I was at most half serious. I was also amused
because it was scripting that I was thinking of as a possible reasonable
use for a recursive call to main. Anyway, any post to a group is open to
comment from all.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
Apr 26 '06 #13
main is the same as the other funcs.it can take argument and has a
return frame

Apr 26 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Jacob Jensen | last post by:
This question has probably been asked a million time, but here it comes again. I want to learn the difference between the three type cast operators: static_cast, reinterpret_cast, dynamic_cast. A...
7
by: yufufi | last post by:
lets say we have a 'shape' class which doesn't implement IComparable interface.. compiler doesn't give you error for the lines below.. shape b= new shape(); IComparable h; h=(IComparable)b;...
33
by: Mark P | last post by:
A colleague asked me something along the lines of the following today. For some type X he has: X* px = new X; Then he wants to convert px to a char* (I'm guessing for the purpose of...
8
by: Kris Jennings | last post by:
Hi, I am trying to create a new generic class and am having trouble casting a generic type to a specific type. For example, public class MyClass<Twhere T : MyItemClass, new() { public...
6
by: Chameleon | last post by:
class A {} class B : public A {} void proceed(vector<A*&in); void main() { vector<B*a; proceed(a); // <-- error here! why? }
8
by: Neha | last post by:
Hi all Its seems bit silly que but pleasee explan me why this error is coming ? and what will be the solution if i want void * to be intilaize by struct * and this code is puerly in C. --...
5
by: brekehan | last post by:
I've always been a little sketchy on the differences between static, dynamic, and reinterpret casting. I am looking to clean up the following block by using C++ casting instead of the C style...
9
by: Jess | last post by:
Hello, It seems both static_cast and dynamic_cast can cast a base class pointer/reference to a derived class pointer/reference. If so, is there any difference between them? In addition, if I...
4
by: Rene | last post by:
If variance/covariance is not allowed in array of value types, why is the expression on the "Main" method run successfully (see snippet below)? I am missing something? Thank you. ...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.