<xmp><body><!--'"</title></head>--> <script type="text/javascript"> //OwnerIQ var __oiq_pct = 50; if( __oiq_pct>=100 || Math.floor(Math.random()*100/(100-__oiq_pct)) > 0 ) { var _oiqq = _oiqq || []; _oiqq.push(['oiq_addPageBrand','Lycos']); _oiqq.push(['oiq_addPageCat','Internet > Websites']); _oiqq.push(['oiq_addPageLifecycle','Intend']); _oiqq.push(['oiq_doTag']); (function() { var oiq = document.createElement('script'); oiq.type = 'text/javascript'; oiq.async = true; oiq.src = document.location.protocol + '//px.owneriq.net/stas/s/lycosn.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(oiq, s); })(); } /////// Google Analytics var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-21402695-21']); _gaq.push(['_setDomainName', 'angelfire.com']); _gaq.push(['_setCustomVar', 1, 'member_name', 'blues2/javeline', 3]); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); ////// Lycos Initialization ///////////////////// var lycos_ad = Array(); var lycos_search_query = ""; var lycos_onload_timer; var cm_role = "live"; var cm_host = "angelfire.lycos.com"; var cm_taxid = "/memberembedded"; var angelfire_member_name = "blues2/javeline"; var angelfire_member_page = "blues2/javeline/programming/self_printers.html"; var angelfire_ratings_hash = "1766502456:b4e352b27765dd50e171d12eea4abac3"; var lycos_ad_category = {"dmoz":"arts\/animation","ontarget":"&CAT=family%20and%20lifestyles&L2CAT=hobbies","find_what":"about popup window"}; var lycos_ad_remote_addr = "209.202.244.9"; var lycos_ad_www_server = "www.angelfire.lycos.com"; var edit_site_url = "www.angelfire.lycos.com/landing/landing.tmpl?utm_source=house&utm_medium=landingpage&utm_campaign=toolbarlink"; </script> <script type="text/javascript" src="https://scripts.lycos.com/catman/init.js"></script> <script type='text/javascript'> var googletag = googletag || {}; googletag.cmd = googletag.cmd || []; (function() { var gads = document.createElement('script'); gads.async = true; gads.type = 'text/javascript'; var useSSL = 'https:' == document.location.protocol; gads.src = (useSSL ? 'https:' : 'http:') + '//www.googletagservices.com/tag/js/gpt.js'; var node = document.getElementsByTagName('script')[0]; node.parentNode.insertBefore(gads, node); })(); </script> <script type='text/javascript'> googletag.cmd.push(function() { googletag.defineSlot('/95963596/ANG_300x250_dfp', [300, 250], 'div-gpt-ad-1450207484070-0').addService(googletag.pubads()); googletag.enableServices(); }); </script> <script type='text/javascript'> googletag.cmd.push(function() { googletag.defineSlot('/95963596/ANG_above_728x90_dfp', [728, 90], 'div-gpt-ad-1450207484070-1').addService(googletag.pubads()); googletag.enableServices(); }); </script> <script type='text/javascript'> googletag.cmd.push(function() { googletag.defineSlot('/95963596/ANG_below_728X90_dfp', [728, 90], 'div-gpt-ad-1450207484070-2').addService(googletag.pubads()); googletag.enableServices(); }); </script> <script type="text/javascript"> (function(isV) { if (!isV) { return; } //this.lycos_search_query = lycos_get_search_referrer(); var adMgr = new AdManager(); var lycos_prod_set = adMgr.chooseProductSet(); var slots = ["leaderboard", "leaderboard2", "toolbar_image", "toolbar_text", "smallbox", "top_promo", "footer2","slider"]; var adCat = this.lycos_ad_category; adMgr.setForcedParam('page', (adCat && adCat.dmoz) ? adCat.dmoz : 'member'); if (this.lycos_search_query) { adMgr.setForcedParam("keyword", this.lycos_search_query); } else if (adCat && adCat.find_what) { adMgr.setForcedParam('keyword', adCat.find_what); } for (var s in slots) { var slot = slots[s]; if (adMgr.isSlotAvailable(slot)) { this.lycos_ad[slot] = adMgr.getSlot(slot); } } adMgr.renderHeader(); adMgr.renderFooter(); }((function() { var w = 0, h = 0, minimumThreshold = 300; if (top == self) { return true; } if (typeof(window.innerWidth) == 'number' ) { w = window.innerWidth; h = window.innerHeight; } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) { w = document.documentElement.clientWidth; h = document.documentElement.clientHeight; } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) { w = document.body.clientWidth; h = document.body.clientHeight; } return ((w > minimumThreshold) && (h > minimumThreshold)); }()))); window.onload = function() { var f = document.getElementById("lycosFooterAd"); var b = document.getElementsByTagName("body")[0]; b.appendChild(f); f.style.display = "block"; document.getElementById('lycosFooterAdiFrame').src = '/adm/ad/footerAd.iframe.html'; // Slider Injection (function() { var e = document.createElement('iframe'); e.style.border = '0'; e.style.margin = 0; e.style.display = 'block'; e.style.cssFloat = 'right'; e.style.height = '254px'; e.style.overflow = 'hidden'; e.style.padding = 0; e.style.width = '300px'; })(); // Bottom Ad Injection ( function() { var b = document.getElementsByTagName("body")[0]; var iif = document.createElement('iframe'); iif.style.border = '0'; iif.style.margin = 0; iif.style.display = 'block'; iif.style.cssFloat = 'right'; iif.style.height = '254px'; iif.style.overflow = 'hidden'; iif.style.padding = 0; iif.style.width = '300px'; iif.src = '/adm/ad/injectAd.iframe.html'; var cdiv = document.createElement('div'); cdiv.style = "width:300px;margin:10px auto;"; cdiv.appendChild( iif ); if( b ) { b.insertBefore(cdiv, b.lastChild); } })(); } </script> <style> #body .adCenterClass { margin:0 auto; display:block !important; overflow:hidden; width:100%; } #body .adCenterClass #ad_container { display:block !important; float:left; width:728px; } @media (min-width: 768px) { <!-- For 300px or less ads ONLY --> #body .adCenterClass #ad_container { width: calc(100% - 372px); } } @media (min-width: 1110px) { <!-- For 728px or less ads --> #body .adCenterClass #ad_container { width: calc(100% - 372px); } } </style> <div style="background:#abe6f6; border-bottom:1px solid #507a87; position:relative; z-index:9999999"> <div class="adCenterClass"> <a href="https://www.angelfire.lycos.com/" title="Angelfire.com: build your free website today!" style="display:block; float:left; width:186px; border:0"> <img src="/adm/ad/angelfire-freeAd.jpg" alt="Site hosted by Angelfire.com: Build your free website today!" style="display:block; border:0" /> </a> <div id="ad_container"> <script type="text/javascript">document.write(lycos_ad['leaderboard']);</script> </div> </div> </div> <!-- ///////////////////////////////////// --> <script type="text/javascript">document.write(lycos_ad['slider']);</script> <div id="lycosFooterAd" style="background:#abe6f6; border-top:1px solid #507a87; clear:both; display:none; position:relative; z-index:9999999"> <div class="adCenterClass" style="display:block!important; overflow:hidden; width:936px;"> <div id="aflinksholder" style="float:left; width:186px;"> <a href="https://www.angelfire.lycos.com/" title="Angelfire.com: build your free website today!" style="display:block; border:0"> <img src="/adm/ad/angelfire-freeAd2.jpg" alt="Site hosted by Angelfire.com: Build your free website today!" style="display:block; border:0" /> </a> </div> <iframe id="lycosFooterAdiFrame" style="border:0; display:block; float:left; height:96px; overflow:hidden; padding:0; width:750px"></iframe> </div> </div> <!--- UNDERDOGMEDIA EDGE_lycos.com JavaScript ADCODE START---> <script data-cfasync="false" language="javascript" async src="//udmserve.net/udm/img.fetch?sid=17754;tid=1;dt=6;"></script> <!--- UNDERDOGMEDIA EDGE_lycos.com JavaScript ADCODE END---> </xmp>
SELF PRINTERS IN C

The definition of self printers is straightforward --- they are simply programs
that print themselves or print their source codes, that is.  You may have seen
these programs before.  Self-printers sparked  my interest when I was in high-
school.  My friend asked me if could make a PASCAL program that could print itself.
I stood up to his challenge and four hours later, I came up with something like:

begin write('begin write(''begin write(''begin write(''...

...and a conclusion: it's a waste of time.  Days later I tried to do the same
trick in C and viola! I came up with the program below after a few minutes.

listing 1. self01.c
char*s="char*s=%s;main(){printf(s,s);}{";main(){printf(s,s);}

What a program like this really needs is something that does double work, a literal
that can be made to print itself twice.  In this case, the variable s which is a
character string.  Using printf(), it is possible to do this because of the unique
way that this function formats its output.  For example, given the following code
fragment:

char *d = "x%s";
printf(d, d);

you should be able to produce the output:

xx%s

clearly demonstrating that d does the double work of specifying the print format
and printing itself.  So given that, the program in listing 1 should be able to print
itself.  Or so I thought.  So what's wrong with it?  As can be seen in a sample run of
the program:

output of self01.c
char*s=char*s=%s;main(){printf(s,s);}{;main(){printf(s,s);}

it is clear that it's missing the double qoutes that delimit the literal value of
char*s.  In the next program, I fixed the bug and came up with a correct output.  It
should work on systems that maps the numeric value 34 to the character \" (ASCII).

listing 2. self02.c
char*s="char*s=%c%s%c;int q=34;main(){printf(s,q,s,q);}";
int q=34;main(){printf(s,q,s,q);}

I won't bother to show the output of this and the other programs below, they're self-
printers all.

listing 3. self03.c
char*s="char*s=%c%s%c;%cint q=34,n=10;main(){printf(s,q,s,q,n);}";
int q=34,n=10;main(){printf(s,q,s,q,n);}

listing 4. self04.c
char *s1="char *s1=%c%s%c;%cchar *s2=%c%s%c;%cchar *s3=%c%s%c;%c";
char *s2="int q=34,n=10;%cmain()%c{%c  printf(s1,q,s1,q,n,q,s2,q,n,q,s3,q,n);";
char *s3="%c  printf(s2,n,n,n);%c  printf(s3,n,n,n);%c}";
int q=34,n=10;
main()
{
  printf(s1,q,s1,q,n,q,s2,q,n,q,s3,q,n);
  printf(s2,n,n,n);
  printf(s3,n,n,n);
}


The program in listing 2 is the shortest I could ever code.  If you have something
shorter, please tell me about it.

- Mark J. P. Documento
javelinexxx@yahoo.com



Any loss of sanity effected by the perusal of the above article will not be a responsibility of the author.
God knows he has enough of this problem himself.



The following response came from mail to the article above which I published at the Planet Source Code.

Mark,

Since you have an interest in self-producing 'C' code, you 
might be interested in http://www.ioccc.org/.  It's the 
home page for the International Obfuscated C Code Contest. 
It's a contest to see who can produce the ugliest, most 
confusing piece of functional c code.  

They used to run a shortest self-producing C code contest 
until someone won by submitting a blank cpp file.  Because 
of an old Unix compiler glitch you could compile a blank 
file, and it would produce an executable that ran and did 
nothing.  And since you can direct input from a program to 
a file in the Unix world.  You could direct the results of 
this program to a file, and the result would be an empty 
file.  So this kind of end that contest.  

And the point of this long e-mail is...... They have an 
archive of all the code from past winners, and you will 
find some nice examples of self-replicating code.
Along with a bunch of interesting/ugly c and cpp code.

Sorry, I didn't intend this e-mail to be this long.

Ryan


Ryan Smulan <smulanry@uregina.ca>

Back to Tutorials and Articles

<xmp></body></xmp>