obfuscated

A

aarklon

Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you


1) what is this under score stuff inside main parenthesis?
2) what does this --_ mean in the initialization condition of for
loop
3) what is the role of this operator _ (unary minus i presume) in
putchar
 
M

Mike Wahler

Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you

Not without seeing all of it.
1) what is this under score stuff inside main parenthesis?
2) what does this --_ mean in the initialization condition of for
loop
3) what is the role of this operator _ (unary minus i presume) in
putchar

No, it's not an operator at all. It's probably a macro whose
definition you're not showing us.

-Mike
 
C

Clever Monkey

Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you
I'll bite. I might be wrong, but I'll bite.
1) what is this under score stuff inside main parenthesis?
It is an illegal (I presume) reference to something like argc. It is
similar to "main(int _)", but very non-standard.

I expect for those compilers that accept this will set "_" to 1 before
we visit the for loop.
2) what does this --_ mean in the initialization condition of for
loop
It predecrements the C identifier "_".
3) what is the role of this operator _ (unary minus i presume) in
putchar
It is not an operator. It is equivalent in ways that count (standard or
not) to "int _".

So, we loop through the char array, getting the _th item in the array,
subtracting 1 and printing the char we get. I suppose this presumes
ASCII collation.
 
A

Ancient_Hacker

Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you


easy. Underscore is an allowed character in an identifier. main(_)
declares it as a parameter in place of argc. argc is 1, so if yo
decrement it, it starts out at zero.
That "J!... " string is just "I love you" with 1 added to each
character.
 
C

Chris Dollin

Mike said:
Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you

Not without seeing all of it.

That /is/ all of it.
No, it's not an operator at all. It's probably a macro whose
definition you're not showing us.

It's the first (and only) argument to `main`. The program has to
be run with no arguments (each argument will ignore another
leading output character, that is if the undefined behaviour [1]
doesn't lead to metapsychic meltdown or penguins at Southend).

It's a bit obvious, really. If it weren't for Yet More Undefined
Behaviour, `_++["J!Mpwf!Zpv\1"]+_` would be better [2], with
appropriate adjustments to the string.

[1] I assume undefined behaviour because `main` wasn't declared in
one of the Two Allowed Ways. And of course it relies on ascii
character codes.

[2] For values of `better` that are ... um ... er ...
 
C

Clever Monkey

Clever said:
Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you
I'll bite. I might be wrong, but I'll bite.
1) what is this under score stuff inside main parenthesis?
It is an illegal (I presume) reference to something like argc. It is
similar to "main(int _)", but very non-standard.

I expect for those compilers that accept this will set "_" to 1 before
we visit the for loop.
(Depending on how this code is run, of course. Try running the
executable with arguments and see what happens...)
 
C

Cong Wang

Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you


1) what is this under score stuff inside main parenthesis?
2) what does this --_ mean in the initialization condition of for
loop
3) what is the role of this operator _ (unary minus i presume) in
putchar

'_' is an argument of main, which is int; '--_' means decrease '_'
first.

The argument of putchar() can be rewritten as

("J!Mpwf!Zpv\1"[_++] )-1

, which is a char in the string "J!Mpwf!Zpv\1".
 
P

Papastefanos Serafeim

Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you


1) what is this under score stuff inside main parenthesis?
2) what does this --_ mean in the initialization condition of for
loop
3) what is the role of this operator _ (unary minus i presume) in
putchar

All right, let's start:
the '_' identifier is used instead of the more well known argc.
Also, the a[1]=1[a] idiom is used.
So, let's
change the program to a more readable version:

main(int argc) {
for(
--argc;
putchar( "J!Mpwf!Zpv\1"[argc++] -1);
) ;
}

well, not much more readable, but now we can understand it:
argc has the value 1 when the program starts, so, when the
for starts, argc will be 0.

Now, while the putchar("...") does not return 0, the loop
will be executed each time and the value of argc will be
increased. And, considering that : J-1 = I, !-1=' '(space),
M-1 = L etc you see how I Love you is printed.

Last point: Why does the loop stop ? Because '\1' - 0 =0,
so, putchar will return 0 and the loop will exit :)

Serafeim Papastefanos
 
A

aarklon

Mike said:
Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you

Not without seeing all of it.
1) what is this under score stuff inside main parenthesis?
2) what does this --_ mean in the initialization condition of for
loop
3) what is the role of this operator _ (unary minus i presume) in
putchar

No, it's not an operator at all. It's probably a macro whose
definition you're not showing us.

-Mike

i am not hiding any macro definition
i actually got this question from my friend which was as follows::

The following code prints "I LOVE YOU".

main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

Avoid the use of digit 1 in above code to print the same output.
Keep in mind not to use direct output text in the code :)
 
J

jmcgill

Mike said:
Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you

Not without seeing all of it.

That's all of it. It's not all that strange.
The mapping of the data to the output is obvious.

_ gets the argc value. It gets decremented. It then is used as an
array index (because n[a] is equivalent to a[n]), and each element of
the array is decremented by one. When it gets to '\0', putchar returns
0 and the for loop ends.
 
J

jmcgill

Clever said:
So, we loop through the char array, getting the _th item in the array,
subtracting 1 and printing the char we get. I suppose this presumes
ASCII collation.

Shouldn't a non-ASCII implementation do the right thing, where 'b' -1 =
'a', regardless of the inner details?
 
R

Richard Bos

jmcgill said:
Shouldn't a non-ASCII implementation do the right thing, where 'b' -1 =
'a', regardless of the inner details?

No. Read the Standard. Only '0'...'9' are required to be subsequent. The
rest need not, and often _but not always_ is subsequent.

Richard
 
F

Frederick Gotham

Aarklon posted:
main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}


(1) If we replace the underscore object name with "i", then we get:

main(i) {for(--i;putchar(i++["J!Mpwf!Zpv\1"]-1););}


(2) If we make explicit the implicit int:

int main(int i) {for(--i;putchar(i++["J!Mpwf!Zpv\1"]-1););}


(3) If we put in white space to make things prettier:

int main(int i)
{
for( --i; putchar(i++["J!Mpwf!Zpv\1"]-1); ) ;
}


(4) If we take "i" out of the loop, and then change it to a "while" loop:

int main(int i)
{
--i;

while( putchar(i++["J!Mpwf!Zpv\1"]-1); );
}


(5) If we change "index[array]" to "array[index]", then we have:

int main(int i)
{
--i;

while( putchar( "J!Mpwf!Zpv\1"[i++] - 1) );
}


(6) If we take the take the string out of the loop to make it clearer:

int main(int i)
{
char const str[] = "J!Mpwf!Zpv\1";

--i;

while (putchar(str[i++] - 1));
}

Armed with the knowledge that "putchar" returns the char it prints, we can
see that we are iterating through each character of the string, subtracting
one from it, then printing it.

The code is non-portable as it makes the unfounded presumption that:

'J' == 'I'+1

Also, I'm not sure if that's a valid signature for "main".
 
F

Flash Gordon

Clever said:
Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you
I'll bite. I might be wrong, but I'll bite.
1) what is this under score stuff inside main parenthesis?
It is an illegal (I presume) reference to something like argc. It is
similar to "main(int _)", but very non-standard.

Actually, the function definition form
foo(arg) {}
Is entirely legal and standard C89 since C89 still allows implicit int
and old K&R style function definitions. The problem is that main takes 0
or 2 arguments, not one. This could be fixed by changing it to

main(_,__)char**__;{for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}
which still keeps it obfusticated.

You can get C99 compliance with
#include<stdio.h>
int main(_,__)int
_;char**__;{for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}
I expect for those compilers that accept this will set "_" to 1 before
we visit the for loop.

<snip>

Unless the user supplies parameters or the environment chooses not to
pass something as the "program name".
 
C

Clever Monkey

Flash said:
Clever said:
can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you

1) what is this under score stuff inside main parenthesis?
It is an illegal (I presume) reference to something like argc. It is
similar to "main(int _)", but very non-standard.

Actually, the function definition form
foo(arg) {}
Is entirely legal and standard C89 since C89 still allows implicit int
and old K&R style function definitions. The problem is that main takes 0
or 2 arguments, not one. This could be fixed by changing it to

main(_,__)char**__;{for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}
which still keeps it obfusticated.
Sure. This is what I meant by "non-standard", since the main() is
malformed and incorrect with respect to the standard. I do understand
that this is a _mostly_ legal function definition; just not for the
function main(). Note my reference to "argc", above.

Furthermore, wasn't there just a thread here about the use of "_" and
"__" being forbidden by the standard under most circumstances? I
suppose an identifier that consists only of these characters would be
contrary to that rule, as well.

Again, this does not speak to the OP, but it indicates that many things
about "main(_)" are probably wrong, regardless of the fact that main()
can be treated just like another function in many cases and that the
default type for untyped identifiers is int.
 
S

Simon Biber

Hi all,

can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you

It doesn't produce that output. The L and Y are capitalised.

If you supply arguments to the program, one letter is lost from the
beginning for each argument you supply. If you supply more than 10
arguments, the program outputs garbage until a 1 byte is found in memory
or the program attempts to read an invalid address and is terminated.


C:\docs\prog\c>type aarklon.c
#include <stdio.h>
main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

C:\docs\prog\c>tcc aarklon.c
Turbo C Version 2.01 Copyright (c) 1987, 1988 Borland International
aarklon.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 394258

C:\docs\prog\c>aarklon 1 2 3 4 5 6 7 8 9 0 1
↕☺☺♥♦♣‼¶♦↕■§♦►☺■■■■■■■■■■■■■♦♦■■■■■■■■■■■■■■■■♫■"☺■♫■■■■↕■■☺☺♦♫☺■■■↕■■■■■■■■
"■■■■"■↕■ z☺z☺z☺ ☼ ☺ ‼☺
 
A

Ancient_Hacker

Frederick said:
The code is non-portable as it makes the unfounded presumption that:

'J' == 'I'+1


Ah yes, any computers out there using the 5-bit Baudot code are going
to print complete gibberish.

Seriously, in IBM EBCDIC, the letters are not contiguous, due to it
being derived from BCD card codes, which as everybody knows, had nine
rows, so the letters are in groups of nine, with seven codes in between
to pad to the next multiple of 16.

But due to pure chance, most of the letters in this phrase are
comfortably away from the abrupt jumps. The only problem is with the
initial "J", which one less than is "}".


Also space is not just before exclamation point, Ampersand is. Also
the ending period gets messed up.

So in EBCDIC it will print out:

}&love&you|
 
F

Frederick Gotham

Ancient_Hacker posted:
Ah yes, any computers out there using the 5-bit Baudot code are going
to print complete gibberish.


Exactly (assuming Baudot code has at least 3 unused bits).

Seriously, in IBM EBCDIC, the letters are not contiguous, due to it
being derived from BCD card codes, which as everybody knows, had nine
rows, so the letters are in groups of nine, with seven codes in between
to pad to the next multiple of 16.


Your use of "Seriously" is not necessary here at comp.lang.c, nor is it even
necessary to provide an example (although I'm glad you did :) ). All we need
to hear is "The Standard doesn't impose such a restriction" and we're bought.
 
F

Flash Gordon

Clever said:
Flash said:
Clever said:
(e-mail address removed) wrote:
can anybody please explain why this code

main(_) {for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

is producing the output:: I love you

1) what is this under score stuff inside main parenthesis?
It is an illegal (I presume) reference to something like argc. It is
similar to "main(int _)", but very non-standard.

Actually, the function definition form
foo(arg) {}
Is entirely legal and standard C89 since C89 still allows implicit int
and old K&R style function definitions. The problem is that main takes
0 or 2 arguments, not one. This could be fixed by changing it to

main(_,__)char**__;{for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}
which still keeps it obfusticated.
Sure. This is what I meant by "non-standard", since the main() is
malformed and incorrect with respect to the standard. I do understand
that this is a _mostly_ legal function definition; just not for the
function main(). Note my reference to "argc", above.

OK, then we are in agreement about what is and is not valid.
Furthermore, wasn't there just a thread here about the use of "_" and
"__" being forbidden by the standard under most circumstances? I
suppose an identifier that consists only of these characters would be
contrary to that rule, as well.

You are right, I should not have used __. Perhals _l or _L would be
sufficiently obscure. That will teach me to rely on memory for a rule
like this. Normally I just don't start identifiers with an _ even where
it would be legal.
Again, this does not speak to the OP, but it indicates that many things
about "main(_)" are probably wrong, regardless of the fact that main()
can be treated just like another function in many cases and that the
default type for untyped identifiers is int.

Well, the _ on its own is acceptable as an identifier as long as it is
not a file scope identifier which it isn't.
 
M

Mark McIntyre

Shouldn't a non-ASCII implementation do the right thing, where 'b' -1 =
'a', regardless of the inner details?

No, this isn't required by the Standard, and indeed realworld
implementations will break this assumption (think non-english
character sets, or EBCDIC or whatever)
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top