English interpretation of this code?

G

genus_

The below code compiles and runs smoothly. Can any one at least explain
to me what its doing for first few lines? Thank you.

Here's the code:

#include <stdio.h>

main(t,_,a)
char *a;
{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
main(-86, 0, a+1 )+a)):1,t<_?main(t+1, _, a ):3,main ( -94, -27+t, a
)&&t == 2 ?_<13 ?main ( 2, _+1, "%s %d %d\n" ):9:16:t<0?t<-72?main(_,
t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+\
,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/\
+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){n\
l]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#\
n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;\
#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")
:t<-50?_==*a ?putchar(a[31]):main(-65,_,a+1):main((*a == '/')+t,_,a\
+1 ):0<t?main ( 2, 2 , "%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc \
i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}
 
A

Alexei A. Frounze

genus_ said:
The below code compiles and runs smoothly. Can any one at least explain
to me what its doing for first few lines? Thank you.
Here's the code:
#include <stdio.h>
main(t,_,a)
char *a;
{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,

Why don't you solve the international obfuscated contest c code yourself?

Alex
 
T

Tim Rentsch

genus_ said:
The below code compiles and runs smoothly. Can any one at least explain
to me what its doing for first few lines?

Sure, no problem.

Here's the code:

#include <stdio.h>

This line imports a standard header for doing I/O such as
'printf'.


This line is a blank separating line, having no effect,
almost certainly put in to aid readability.

main(t,_,a)

This line starts the definition of the function 'main', with
three parameters. The omission of a return type means the
return type defaults to 'int' (allowed under C89/C90).


This line declares parameter 'a' (using the old K&R-style
parameter declaration syntax) to have type 'char *'.

{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,

This line commences the function definition and gives the
beginning of the 'return' statement that determines the
value of the 'main' function.


[...lines after the first few lines snipped...]
Thank you.

Don't mention it.
 
R

roczhong

C:\>obfuscated.exe
On the first day of Christmas my true love gave to me
a partridge in a pear tree.

On the second day of Christmas my true love gave to me
two turtle doves
and a partridge in a pear tree.

On the third day of Christmas my true love gave to me
three french hens, two turtle doves
and a partridge in a pear tree.

On the fourth day of Christmas my true love gave to me
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the fifth day of Christmas my true love gave to me
five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the sixth day of Christmas my true love gave to me
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the seventh day of Christmas my true love gave to me
seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the eighth day of Christmas my true love gave to me
eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the ninth day of Christmas my true love gave to me
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the tenth day of Christmas my true love gave to me
ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the eleventh day of Christmas my true love gave to me
eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the twelfth day of Christmas my true love gave to me
twelve drummers drumming, eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.
 
G

genus_

It is? Interesting. So there are many more of these obfuscated c codes?
I didn't realise.
 
S

Skarmander

genus_ wrote:
main(t,_,a)
char *a;
{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
<snip>

While we're on the subject: I seem to recall that calling main() from
within the program results in undefined behaviour, but maybe that was
just C++. Can anyone confirm/deny?

S.
 
C

Christopher Benson-Manica

Skarmander said:
While we're on the subject: I seem to recall that calling main() from
within the program results in undefined behaviour, but maybe that was
just C++. Can anyone confirm/deny?

It's just C++. Calling main() recursively is permissible in C, both
C89 and C99 IIRC.
 
W

Walter Roberson

While we're on the subject: I seem to recall that calling main() from
within the program results in undefined behaviour, but maybe that was
just C++. Can anyone confirm/deny?

I do not find anything in C89 that would indicate undefined behaviour
for recusively calling main().

The closest that I find in C89 is a slightly lax wording.

C89 2.1.2.2.3 Program Termination

A return from the initial call to the main function is equivilent
to calling the exit function with the value returned by the main
function as its argument. If the main function executes a return
that specifies no value, the termination status returned to the host
environment is undefined.

The laxness is that when it says "if the main function executes a
return that specifies no value", it does not explicitly constrain
consideration of that condition to the -initial- call to main. One
could thus advance the claim that if -any- of the executed returns from
main did not specify a value, that the termination status is undefined,
even if the -final- return from main returned a value. But I think
it pretty unlikely that any real implementation would take this
"gotcha!" approach.


What -is- troublesome about main() starts from the fact that main()
is the only function which may be legally declared with 0 or 2 arguments.
For every other function, it would be legal for the calling procedure
with 0 arguments to be incompatible with the calling procedure for 2
arguments, since for every other non-vararg routine, calling with the
"wrong" number of arguments is not allowed. Any hidden OS glue
in an executable for initializations and getting the arguments into
place, is implementation specific and doesn't have to follow
normal calling conventions (nor be written in C), so the OS can do
whatever it needs to do to accomedate this special feature of main().

But... what happens when one wants to use main() via a function pointer?
Which of the two calling hypothetically-incompatible calling conventions
does one use? The prototype for main() might be out of scope --
or one might want to use the two hypothetically-different calling
conventions within the same scope, and one might not know until runtime
which of the two one wanted to use.

So... this ambiguity of definitions of main() might end up forcing
the use of compatible calling conventions for the two cases, when
that compatibility might not be needed for any other routine. But
for portability, one doesn't *know* what the underlying calling
convention is, so if one wants to use main() in this ambiguous
way allowed for by the standard, one gets into icky territory.
 
K

Keith Thompson

genus_ said:
It is? Interesting. So there are many more of these obfuscated c codes?
I didn't realise.

What is what? Please provide context when you post a followup.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

And see <http://www.ioccc.org/> -- but always keep in mind that the
entries are intended to show how *not* to program in C. Cleverness is
not nearly the virtue that some might think it is.
 
K

Keith Thompson

What -is- troublesome about main() starts from the fact that main()
is the only function which may be legally declared with 0 or 2 arguments.
For every other function, it would be legal for the calling procedure
with 0 arguments to be incompatible with the calling procedure for 2
arguments, since for every other non-vararg routine, calling with the
"wrong" number of arguments is not allowed. Any hidden OS glue
in an executable for initializations and getting the arguments into
place, is implementation specific and doesn't have to follow
normal calling conventions (nor be written in C), so the OS can do
whatever it needs to do to accomedate this special feature of main().

But... what happens when one wants to use main() via a function pointer?
Which of the two calling hypothetically-incompatible calling conventions
does one use? The prototype for main() might be out of scope --
or one might want to use the two hypothetically-different calling
conventions within the same scope, and one might not know until runtime
which of the two one wanted to use.

If you call main() recursively through a function pointer with no
prototype in scope, it may or may not be undefined behavior, but
demons *should* fly out your nose. :cool:}
 
A

Alexei A. Frounze

....
prototype in scope, it may or may not be undefined behavior, but
demons *should* fly out your nose. :cool:}

For some reason I adore and cherish them... They were made so cute by
desing. ;)

Alex
 
P

Peter Nilsson

Walter said:
...
What -is- troublesome about main() starts from the fact that main()
is the only function which may be legally declared with 0 or 2
arguments. For every other function, it would be legal for the
calling procedure with 0 arguments to be incompatible with the
calling procedure for 2 arguments, since for every other non-vararg
routine, calling with the "wrong" number of arguments is not allowed.

You can only call main with the correct number of arguments as per
its definition. [Although a non strictly conforming program could
delcare main as a variadic function if a given implementation accepted
it.]
Any hidden OS glue in an executable for initializations and getting
the arguments into place, is implementation specific and doesn't have
to follow normal calling conventions (nor be written in C), so the OS
can do whatever it needs to do to accomedate this special feature of
main().

Typically the runtime startup code doesn't do anything special for
main, it's just another function name. On many systems you can replace
the name of the entry function with whatever you like. [e.g. free-
standing implementations often allow this.]
But... what happens when one wants to use main() via a function
pointer?

Nothing different to using a function pointer with any other function.
Note that your function pointer and arguments must match the actual
definition of main in your code.
Which of the two calling hypothetically-incompatible calling
conventions does one use?

Why do you think there needs to be distinct calling conventions?

Have you considered that a conforming implementation must support
calls to non-prototyped functions correctly? You seem to think
that functions with different number of parameters somehow each
need a different calling convention.
The prototype for main() might be out of scope --
or one might want to use the two hypothetically-different calling
conventions within the same scope, and one might not know until
runtime which of the two one wanted to use.

So... this ambiguity of definitions of main() might end up forcing
the use of compatible calling conventions for the two cases, when
that compatibility might not be needed for any other routine. But
for portability, one doesn't *know* what the underlying calling
convention is, so if one wants to use main() in this ambiguous
way allowed for by the standard, one gets into icky territory.

I don't understand why you think it's icky.

If you want to take the discussion to another forum, we can discus
typical calling conventions on different (or even the same) machines,
and the fact that the requirements of C typically won't pose
particular problems.

It's only C99's (and C++'s) requirement that an int main without
return must (ultimately) return a successful status to the host
that causes minor problems. But the typical solution for that has
nothing to do with function calling conventions.
 
L

Lawrence Kirby

I do not find anything in C89 that would indicate undefined behaviour
for recusively calling main().

There isn't anything, recursive calling of main is allowed in C.
The closest that I find in C89 is a slightly lax wording.

C89 2.1.2.2.3 Program Termination

A return from the initial call to the main function is equivilent
to calling the exit function with the value returned by the main
function as its argument. If the main function executes a return
that specifies no value, the termination status returned to the host
environment is undefined.

The laxness is that when it says "if the main function executes a
return that specifies no value", it does not explicitly constrain
consideration of that condition to the -initial- call to main.

The whole paragraph is talking about an initial call to main. There is no
need to repeat that for every sentence. The paragraph is in a section
called "Program Termination" so what it says is relevant to that situation.
One
could thus advance the claim that if -any- of the executed returns from
main did not specify a value, that the termination status is undefined,
even if the -final- return from main returned a value. But I think
it pretty unlikely that any real implementation would take this
"gotcha!" approach.

If it isn't an initial call to main there is no termination status to be
defined or otherwise.
What -is- troublesome about main() starts from the fact that main()
is the only function which may be legally declared with 0 or 2 arguments.

Most other user-defined functions can be defined in many, many different
ways.
For every other function, it would be legal for the calling procedure
with 0 arguments to be incompatible with the calling procedure for 2
arguments, since for every other non-vararg routine, calling with the
"wrong" number of arguments is not allowed.

The same is true for main(), any call in program code must be compatible
with main()'s definition.

Any hidden OS glue
in an executable for initializations and getting the arguments into
place, is implementation specific and doesn't have to follow
normal calling conventions (nor be written in C), so the OS can do
whatever it needs to do to accomedate this special feature of main().
Right

But... what happens when one wants to use main() via a function pointer?
Which of the two calling hypothetically-incompatible calling conventions
does one use?

Like any other function the function call must be compatible with how
main() is defined in that program, and in any particular program it can
only be defined one way.
The prototype for main() might be out of scope --
or one might want to use the two hypothetically-different calling
conventions within the same scope, and one might not know until runtime
which of the two one wanted to use.

Which one you must use is cast in stone when main() is compiled.
So... this ambiguity of definitions of main() might end up forcing
the use of compatible calling conventions for the two cases, when
that compatibility might not be needed for any other routine. But
for portability, one doesn't *know* what the underlying calling
convention is, so if one wants to use main() in this ambiguous
way allowed for by the standard, one gets into icky territory.

It is no mor ambiguous than if you defined a function

int foo(void)
{
return 0;
}

and then later changed it to

int foo(int bar, char **baz)
{
return 0;
}

In either case the caller has to be compatible with the definition of the
function that it is linked to at the time.

Lawrence
 
M

Mabden

C:\>obfuscated.exe
On the first day of Christmas my true love gave to me
a partridge in a pear tree.
....

On the twelfth day of Christmas my true love gave to me
twelve drummers drumming, eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

Yeah, why does that Bitch keep doing that?!! I threw out her number 3
months ago. She had the miscarriage. But she keeps calling, and sending
stuff over... I'm just gonna have to set her up with Keith, I guess...
 
K

Keith Thompson

Mabden said:
Yeah, why does that Bitch keep doing that?!! I threw out her number 3
months ago. She had the miscarriage. But she keeps calling, and sending
stuff over... I'm just gonna have to set her up with Keith, I guess...

You're not nearly as funny as you seem to think you are, and I resent
your dragging my name into this. Good-bye.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

weird code!!! 7
how this program works 10
Stupid question 19
Fibonacci 0
Python code problem 2
Why is 'i' equal to 7?I know it's super simple but can anyone help me? 1
My Status, Ciphertext 2
Blue J Ciphertext Program 2

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,219
Latest member
KristieKoh

Latest Threads

Top