Quines

T

Tarique

Hello.Can anyone please explain why the output of the following
code is Hello? No header file is included and the code works (Compiled
as a 'c' code with the strictest warning level on Visual C++ 2008(express) !

I get the two warnings :
1.warning C4431: missing type specifier - int assumed. Note: C no longer
supports default-int
2.warning C4013: 'printf' undefined; assuming extern returning int

main()
{
char *c="Hello";
printf(c,34,c,34);
}
The code prints Hello irrespective of the integer values used in the
printf statement(both +ve and -ve)

______________________________________________________________________

Secondly.

#include<stdio.h>
main() {

char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c
;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n";

printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]); /*What about this line?*/
exit(0);
}

Can anyone explain what happens in the printf statement?

Thank You
 
U

user923005

Hello.Can anyone please explain why the output of the following
code is Hello? No header file is included and the code works (Compiled
as a 'c' code with the strictest warning level on Visual C++ 2008(express) !

I get the two warnings :
1.warning C4431: missing type specifier - int assumed. Note: C no longer
supports default-int
2.warning C4013: 'printf' undefined; assuming extern returning int

This is undefined behavior. You are calling a varadic function
without the presence of a prototype.
main()
{
        char *c="Hello";
        printf(c,34,c,34);}

The code prints Hello irrespective of the integer values used in the
printf statement(both +ve and -ve)

There are no conversion specifiers in the format string.
______________________________________________________________________

Secondly.

#include<stdio.h>
main() {

char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c
;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n";

printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]); /*What about this line?*/
exit(0);

Your format string starts at the 3rd character of c. Notice the %c
before main()? That is the first format specifier. The rest should
be obvious.
 
J

jameskuyper

Tarique said:
Hello.Can anyone please explain why the output of the following
code is Hello? No header file is included and the code works (Compiled
as a 'c' code with the strictest warning level on Visual C++ 2008(express) !

It works because sometimes you have an unlucky accident which makes
defective code appear to work correctly. You shouldn't worry too much
about the details of why; just correct your code.
I get the two warnings :
1.warning C4431: missing type specifier - int assumed. Note: C no longer
supports default-int es it easier
2.warning C4013: 'printf' undefined; assuming extern returning int

The correct return type of printf() happens to be 'int', so that
assumption accidentally worked. On the other hand, it should have
assumed that printf() is an ordinary function, not a variadic one,
which could in principle cause problems.
main()
{
char *c="Hello";
printf(c,34,c,34);
}

Since your program printed "Hello", it seems likely that the argument
passing conventions for variadic functions for this compiler are
compatible with those for ordinary functions, at least when you never
access the variable arguments, as in this case.
The code prints Hello irrespective of the integer values used in the
printf statement(both +ve and -ve)

Since the first 'c' was interpreted as format string that contained no
format specifiers, printf() had no reason to read any of it's other
arguments.
______________________________________________________________________

Secondly.

#include<stdio.h>
main() {

char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]) exit(0);} \n";

printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]); /*What about this line?*/
exit(0);
}

Can anyone explain what happens in the printf statement?

Where did you get that code? Is it from an obfuscated C contest?
Simple rule: never write code like that. However, if you insist on
trying to figure it out, I recommend taking a little bit longer to
look at it before asking for help; it's awful because it's complicated
and hard to read, but the features of C that it uses are all
relatively straightforward - you should be able to solve it without
asking for help.
 
J

JimS

Hello.Can anyone please explain why the output of the following
code is Hello? No header file is included and the code works (Compiled
as a 'c' code with the strictest warning level on Visual C++ 2008(express) !

I get the two warnings :
1.warning C4431: missing type specifier - int assumed. Note: C no longer
supports default-int
2.warning C4013: 'printf' undefined; assuming extern returning int

main()
{
char *c="Hello";
printf(c,34,c,34);
}
The code prints Hello irrespective of the integer values used in the
printf statement(both +ve and -ve)

main returns an int. You should write
int main(void)
and
return 0, EXIT_FAILURE or EXIT_SUCCESS

#include <stdio.h> before you use printf
Check your compiler documentation for how it's supposed to work.

Jim
 
U

user923005

It works because sometimes you have an unlucky accident which makes
defective code appear to work correctly. You shouldn't worry too much
about the details of why; just correct your code.




The correct return type of printf() happens to be 'int', so that
assumption accidentally worked. On the other hand, it should have
assumed that printf() is an ordinary function, not a variadic one,
which could in principle cause problems.

The return type is irrelevant (unless, perhaps, that is the only
problem). A varadic function may unpile the automatic storage needed
for the function call differently (indeed, I have known compilers that
did this). It would appear to the compiler as an integer function
that takes four arguments but it isn't: it is a varadic function
returning int, and for which the first element is a character pointer.
 
J

Jack Klein

It works because sometimes you have an unlucky accident which makes
defective code appear to work correctly. You shouldn't worry too much
about the details of why; just correct your code.


The correct return type of printf() happens to be 'int', so that
assumption accidentally worked. On the other hand, it should have
assumed that printf() is an ordinary function, not a variadic one,
which could in principle cause problems.


Since your program printed "Hello", it seems likely that the argument
passing conventions for variadic functions for this compiler are
compatible with those for ordinary functions, at least when you never
access the variable arguments, as in this case.

Since the behavior is completely undefined, how do you know that? It
could outputting the third argument. Or the string literal from the
source code file fed to the compiler.
Since the first 'c' was interpreted as format string that contained no
format specifiers, printf() had no reason to read any of it's other
arguments.

You're assuming it is using the first 'c'. Occam's razor says that is
most likely, but certainly not guaranteed.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
T

Tarique

Tarique wrote:
......snip......
Secondly.

#include<stdio.h>
main() {

char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]) exit(0);} \n";

printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]); /*What about this line?*/
exit(0);
}

Can anyone explain what happens in the printf statement?

Where did you get that code? Is it from an obfuscated C contest?
Simple rule: never write code like that. However, if you insist on
trying to figure it out, I recommend taking a little bit longer to
look at it before asking for help; it's awful because it's complicated
and hard to read, but the features of C that it uses are all
relatively straightforward - you should be able to solve it without
asking for help.

This is the source:
http://www.nyx.net/~gthompso/self_c.txt
 
T

Tarique

JimS said:
....snip...

main returns an int. You should write
int main(void)
and
return 0, EXIT_FAILURE or EXIT_SUCCESS

#include <stdio.h> before you use printf
Check your compiler documentation for how it's supposed to work.

Jim

Thank You for pointing that out,but the codes are not mine(I am not
exactly a complete newbie as well).In fact i was amazed at the output n
hence i needed the explanation. :)
 
K

Keith Thompson

user923005 said:
This is undefined behavior. You are calling a varadic function
without the presence of a prototype.


There are no conversion specifiers in the format string.

Right. *If* there were a proper "#include <stdio.h>", providing a
valid declaration for printf(), then, since the first argument points
to a string containing no "%" characters, the remaining arguments
would be ignored. More generally, the format string specifies which
arguments (if any) are to be processed; any arguments not consumed by
the format string are quietly ignored (except that any side effects
will take place).

[...]
 
J

James Kuyper

Jack said:
Since the behavior is completely undefined, how do you know that? It
could outputting the third argument. Or the string literal from the
source code file fed to the compiler.

Sure, it could do literally anything. Pay attention to my wording - I
said "it seems likely", not "it is required by the standard". I've
already expressed the fact that this code is defective, and should
simply be corrected. The OP wanted to know why his clearly defective
code seemed to "work"; I was merely making plausible guesses as to the
way in which the undefined behavior of the code turned out to be the
behavior he actually observed.
You're assuming it is using the first 'c'. Occam's razor says that is
most likely, but certainly not guaranteed.

Yes, I was shaving with Occam's razor, not talking about what is
guaranteed by the standard.
 
J

James Kuyper

Tarique said:
Thank You for pointing that out,but the codes are not mine(I am not
exactly a complete newbie as well).In fact i was amazed at the output n
hence i needed the explanation. :)

OK, here goes:


#include<stdio.h>
main() {

char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c
;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n";

printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]); /*What about this line?*/
exit(0);
}

The line on which 'c' is initialized is hard to read, the trickiest
point is noticing that the second '"' character is escaped, so that it's
the third '"' character that actually terminates the string.

Now, c+2 points at the following string, which serves as the format
string for this call:

"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c
;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n"

Note that this format string contains 7 '%' characters, each of which
starts a format specifier; the other characters in the format string are
simply printed as shown. I think it will be clearer what is happening if
I write 8 printf() statements that will print the same output as the
original printf():

printf("#include<stdio.h>%c", c[102]); // c[102] == '\n'
printf("main(){char*c=%c", *c); // c[1] == '"'
printf("%c", *c); // *c == '\\'
printf("%c", *c); // *c == '\\'
printf("%.102s", c); // Prints the first 102 characters of c.
printf("%c", *c); // *c == '\\'
printf("n%c", c[1]); // c[1] == '"'
printf("printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n");

Of course, it would no longer qualify as a Quine if it were written that
way.
 
S

Spiros Bousbouras

Hello.Can anyone please explain why the output of the following
code is Hello? No header file is included and the code works (Compiled
as a 'c' code with the strictest warning level on Visual C++ 2008(express) !

I get the two warnings :
1.warning C4431: missing type specifier - int assumed. Note: C no longer
supports default-int
2.warning C4013: 'printf' undefined; assuming extern returning int

main()
{
        char *c="Hello";
        printf(c,34,c,34);}

The code prints Hello irrespective of the integer values used in the
printf statement(both +ve and -ve)

______________________________________________________________________

Secondly.

#include<stdio.h>
main() {

char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c
;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n";

printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]); /*What about this line?*/
exit(0);

}

Can anyone explain what happens in the printf statement?

Others have pointed out that the first piece of code causes undefined
behaviour. The second piece of code also causes undefined behaviour
because there's no prototype for exit(). Ignoring that others have
already made guesses on how printf() probably behaves.
 
A

Army1987

James said:
Tarique wrote:
...

I like the last example, by smr. :)

When I try to compile it, I get:
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
 
K

Kenneth Brody

Army1987 said:
When I try to compile it, I get:
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status

[Note: The example from smr is an empty file, and won the "Worst
Abuse of the Rules" award at the 1994 Obfuscated C Code contest.]

Meaning that you cannot run the program, meaning that no output will
be generated, meaning that you have just generated the source code.
(Perhaps the original rules allowed such a loophole?)

[/tmp]$ >empty.c
[/tmp]$ cc -o empty empty.c
/usr/lib/crt1.o: In function `_start':
/usr/lib/crt1.o(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
[/tmp]$ ./empty >empty.output
bash: ./empty: No such file or directory
[/tmp]$ ls -l empty*
-rw-rw-r-- 1 hvcomput hvcomput 0 Jan 11 17:49 empty.c
-rw-rw-r-- 1 hvcomput hvcomput 0 Jan 11 17:49 empty.output
[/tmp]$ sum empty*
00000 0 empty.c
00000 0 empty.output
[/tmp]$

Note that "empty.c" and "empty.output" are identical. QED.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
H

Harald van Dijk

[Note: The example from smr is an empty file, and won the "Worst Abuse
of the Rules" award at the 1994 Obfuscated C Code contest.]

Meaning that you cannot run the program, meaning that no output will be
generated, meaning that you have just generated the source code.
(Perhaps the original rules allowed such a loophole?)

No, that is not the loophole.

Quoting from <http://www.de.ioccc.org/1994/smr.hint>:

While strictly speaking, smr.c is not a valid C program, it is
not an invalid C program either! Some C compilers will compile
an empty file into a program that does nothing. But even if your
compiler can't, the build instructions supplied with this entry
will produce an executable file. On most systems, the stdout
from the executable will exactly match original source.

Of course, this is wrong as far as relevant for this group. While
compilers are certainly allowed to translate empty source files into
executables that do nothing, or even executables that do something, such
programs violate a constraint and the compiler must issue a diagnostic.
If the implementation chooses not to make this diagnostic a hard error,
that's fine, but it doesn't make the code any less invalid as C.

(And the build instructions referenced don't interpret the program as C
source code.)
 
B

Barry Schwarz

Hello.Can anyone please explain why the output of the following
code is Hello? No header file is included and the code works (Compiled
as a 'c' code with the strictest warning level on Visual C++ 2008(express) !

I get the two warnings :
1.warning C4431: missing type specifier - int assumed. Note: C no longer
supports default-int
2.warning C4013: 'printf' undefined; assuming extern returning int

main()
{
char *c="Hello";
printf(c,34,c,34);
}
The code prints Hello irrespective of the integer values used in the
printf statement(both +ve and -ve)

The first argument to printf is a format string. In this case, the
string is "Hello". The string does not contain any format
specification. Therefore, all the other arguments to printf are
ignored and only the string is printed. It is exactly the same as
printf("Hello");
______________________________________________________________________

Secondly.

#include<stdio.h>
main() {

char*c="\\\"#include<stdio.h>%cmain(){char*c=%c%c%c%.102s%cn%c
;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n";

printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]); /*What about this line?*/
exit(0);
}

Can anyone explain what happens in the printf statement?

Take a piece of paper and work it out. It will make a much stronger
impression if you derive it rather than us spoon feeding it to you.
What does c+2 point to? What will printf do with this string? What
is the value of c[102]? When will printf want to process that value?
Repeat for the remaining arguments.


Remove del for email
 

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
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top