<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tlrobinson.net blog &#187; GCC</title>
	<atom:link href="http://tlrobinson.net/blog/category/gcc/feed/" rel="self" type="application/rss+xml" />
	<link>http://tlrobinson.net/blog</link>
	<description></description>
	<lastBuildDate>Mon, 06 Apr 2009 08:37:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Overriding library functions in Mac OS X, the easy way: DYLD_INSERT_LIBRARIES</title>
		<link>http://tlrobinson.net/blog/2007/12/overriding-library-functions-in-mac-os-x-the-easy-way-dyld_insert_libraries/</link>
		<comments>http://tlrobinson.net/blog/2007/12/overriding-library-functions-in-mac-os-x-the-easy-way-dyld_insert_libraries/#comments</comments>
		<pubDate>Fri, 21 Dec 2007 09:31:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[GCC]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=30</guid>
		<description><![CDATA[Back at MacHack 2003 Jonathan Rentzsch talked about how to override functions and inject code in Mac OS X using [several neat tricks](http://rentzsch.com/papers/overridingMacOSX). He also released a framework called [mach_star](http://rentzsch.com/mach_star/) which has two components: mach_override and mach_inject. These are great, &#8230; <a href="http://tlrobinson.net/blog/2007/12/overriding-library-functions-in-mac-os-x-the-easy-way-dyld_insert_libraries/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Back at MacHack 2003 Jonathan Rentzsch talked about how to override functions and inject code in Mac OS X using [several neat tricks](http://rentzsch.com/papers/overridingMacOSX). He also released a framework called [mach_star](http://rentzsch.com/mach_star/) which has two components: mach_override and mach_inject. These are great, but overkill for some simple cases.</p>
<p>A much easier way of doing library function overrides is using the DYLD_INSERT_LIBRARIES environment variable (analogous to LD_PRELOAD on Linux). The concept is simple: at load time the dynamic linker (dyld) will load any dynamic libraries specified in DYLD_INSERT_LIBRARIES before any libraries the executable wants loaded. By naming a function the same as one in a library function it will override any calls to the original.</p>
<p>The original function is also loaded, and can be retrieved using the dlsym(RTLD_NEXT, &#8220;function_name&#8221;); function. This allows a simple method of wrapping existing library functions.</p>
<p>Here&#8217;s a simple example which prints out the path of every file opened using the &#8220;fopen&#8221; function (lib_overrides.c):</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#683821;">#include &lt;stdio.h&gt;<br />
#include &lt;unistd.h&gt;<br />
#include &lt;dlfcn.h&gt;<br />
</span><br />
<span style="color:#236e25;">// for caching the original fopen implementation<br />
</span>FILE * (*original_fopen) (<span style="color:#881350;">const</span> <span style="color:#881350;">char</span> *, <span style="color:#881350;">const</span> <span style="color:#881350;">char</span> *) = <span style="color:#881350;">NULL</span>;</p>
<p><span style="color:#236e25;">// our fopen override implmentation<br />
</span>FILE * <span style="color:#003369;">fopen</span>(<span style="color:#881350;">const</span> <span style="color:#881350;">char</span> * filename, <span style="color:#881350;">const</span> <span style="color:#881350;">char</span> * mode)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// if we haven&#8217;t already, retrieve the original fopen implementation<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(!original_fopen)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;original_fopen = <span style="color:#003369;">dlsym</span>(RTLD_NEXT, <span style="color:#760f15;">&quot;fopen&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// do our own processing; in this case just print the parameters<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;== fopen: {%s,%s} ==\n&quot;</span>, filename, mode);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// call the original fopen with the same arugments<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;FILE* f = <span style="color:#003369;">original_fopen</span>(filename, mode);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// return the result<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> f;<br />
}</div>
<p>And a simple test program (overrides_test.c):</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "><span style="color:#683821;">#include &lt;stdio.h&gt;<br />
#include &lt;string.h&gt;<br />
</span><br />
<span style="color:#881350;">int</span> <span style="color:#003369;">main</span>(<span style="color:#881350;">int</span> argc, <span style="color:#881350;">char</span> <span style="color:#881350;">const</span> *argv[])<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">char</span> hello[] = <span style="color:#760f15;">&quot;hello world&quot;</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp = <span style="color:#003369;">fopen</span>(<span style="color:#760f15;">&quot;hello.txt&quot;</span>, <span style="color:#760f15;">&quot;w&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(fp) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fwrite</span>(hello, <span style="color:#0000ff;">1</span>, <span style="color:#003369;">strlen</span>(hello), fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fclose</span>(fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#0000ff;">0</span>;<br />
}</div>
<p>Compiled and tested:</p>
<p>    tlrobinson$ gcc -Wall -o lib_overrides.dylib -dynamiclib lib_overrides.c<br />
    tlrobinson$ gcc -Wall -o overrides_test overrides_test.c<br />
    tlrobinson$ DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=lib_overrides.dylib overrides_test<br />
    == fopen: {hello.txt,w} ==<br />
    tlrobinson$</p>
<p>There are certainly scenarios far more interesting than this, though!</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2007/12/overriding-library-functions-in-mac-os-x-the-easy-way-dyld_insert_libraries/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Presenting GCCalc: a horrible abuse of GCC</title>
		<link>http://tlrobinson.net/blog/2007/12/presenting-gccalc-a-horribly-awesome-abuse-of-gcc/</link>
		<comments>http://tlrobinson.net/blog/2007/12/presenting-gccalc-a-horribly-awesome-abuse-of-gcc/#comments</comments>
		<pubDate>Fri, 14 Dec 2007 09:02:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Command line]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://tlrobinson.net/blog/?p=31</guid>
		<description><![CDATA[Following an [interesting discussion on Reddit](http://programming.reddit.com/info/62v70/comments) about [first class functions](http://en.wikipedia.org/wiki/First-class_function) in C, I was inspired to see what I could do with this new-found knowledge. The result is what I affectionately call &#8220;GCCalc&#8221;, for reasons that will become clear below. &#8230; <a href="http://tlrobinson.net/blog/2007/12/presenting-gccalc-a-horribly-awesome-abuse-of-gcc/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Following an [interesting discussion on Reddit](http://programming.reddit.com/info/62v70/comments) about [first class functions](http://en.wikipedia.org/wiki/First-class_function) in C, I was inspired to see what I could do with this new-found knowledge. The result is what I affectionately call &#8220;GCCalc&#8221;, for reasons that will become clear below.</p>
<p>GCCalc is a simple command line calculator, much like the common [bc](http://en.wikipedia.org/wiki/Bc_programming_language) calculator on many Unix systems. It&#8217;s implementation, however, is *very* different than most calculators. While bc is said to have &#8220;C-like syntax&#8221;, GCCalc&#8217;s syntax *is* C. Whatever you enter on the command line automatically gets compiled, loaded, and executed, and the result is returned (as a double) and printed to the screen.</p>
<p>You can either enter expressions like:</p>
<p>    round(46.95886*sqrt(1+2/9.99*sin((21%5)*pow(2,8))))</p>
<p>or you can enter whole C statements (as long as they&#8217;re on one line, for now) like:</p>
<p>     int i; for (i=0;i<10;i++) { printf("hello world!\n"); } printf("goodbye\n");</p>
<p>Unfortunately variables are scoped to the function that wraps them, so they don't persist across multiple entries. However, you can access the last result using the "last" variable (a double).</p>
<p>[Here's the source file](http://tlrobinson.net/projects/gccalc/gccalc.c), and here's a syntax highlighted version:</p>
<p>It's been tested on Mac OS X (Leopard) and Linux (Ubuntu Gutsy), with GCC 4. Compile with "gcc -o gccalc gccalc.c" on OS X, or "gcc -o gccalc gccalc.c -ldl" on Linux.</p>
<div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; ">
<span style="color:#683821;">#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;dlfcn.h&gt;<br />
#include &lt;unistd.h&gt;<br />
</span><br />
<span style="color:#683821;">#ifdef __ELF__<br />
#define GCC_FLAGS &quot;-fPIC -shared&quot;<br />
#define EXTENSION &quot;so&quot;<br />
#else<br />
#define GCC_FLAGS &quot;-dynamiclib&quot;<br />
#define EXTENSION &quot;dylib&quot;<br />
#endif<br />
</span><br />
<span style="color:#683821;">#define HEADERS &quot;#include &lt;stdio.h&gt;\n#include&lt;math.h&gt;&quot;<br />
</span><br />
<span style="color:#881350;">typedef</span> <span style="color:#881350;">double</span>(func_return_double)(<span style="color:#881350;">double</span>);</p>
<p><span style="color:#881350;">unsigned</span> count = <span style="color:#0000ff;">0</span>;<br />
<span style="color:#881350;">char</span> *cwd;<br />
<span style="color:#881350;">char</span> tmp_path[<span style="color:#0000ff;">1024</span>] = {<span style="color:#0000ff;">&#8216;\0&#8242;</span>};</p>
<p><span style="color:#881350;">void</span> *lib = <span style="color:#881350;">NULL</span>;</p>
<p><span style="color:#881350;">int</span> <span style="color:#003369;">main</span>(<span style="color:#881350;">int</span> argc, <span style="color:#881350;">char</span> **argv)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">double</span> result = <span style="color:#0000ff;">0.0</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">char</span> input_buffer[<span style="color:#0000ff;">1024</span>], code_buffer[<span style="color:#0000ff;">2048</span>], function_name[<span style="color:#0000ff;">32</span>], command_buffer[<span style="color:#0000ff;">1024</span>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// get out current directory, which we&#8217;ll use for tmp files (dlopen seems to need absolute paths)<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;cwd = <span style="color:#003369;">getcwd</span>(<span style="color:#881350;">NULL</span>, <span style="color:#0000ff;">0</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">while</span><span style="color:#003369;"> </span>(<span style="color:#0000ff;">1</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// for unique function and file names (needed for dlopen/dlsym to work correctly)<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// read in the next line<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;&gt;&gt; &quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fgets</span>(input_buffer, <span style="color:#881350;">sizeof</span>(input_buffer), stdin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the function name<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(function_name, <span style="color:#760f15;">&quot;f%d&quot;</span>, count);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the code string: if it doesn&#8217;t contain a semicolon, assume it is just an expression<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(<span style="color:#003369;">strchr</span>(input_buffer, <span style="color:#0000ff;">&#8216;;&#8217;</span>))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(code_buffer, <span style="color:#760f15;">&quot;%s\ndouble %s(double last) { %s\nreturn 0; }&quot;</span>, HEADERS, function_name, input_buffer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(code_buffer, <span style="color:#760f15;">&quot;%s\ndouble %s(double last) { return (%s); }&quot;</span>, HEADERS, function_name, input_buffer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the filename string, delete the file if it exists<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(tmp_path, <span style="color:#760f15;">&quot;%s/libtmp%d.%s&quot;</span>, cwd, count, EXTENSION);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">unlink</span>(tmp_path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// format the gcc command string<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">sprintf</span>(command_buffer, <span style="color:#760f15;">&quot;gcc -Wall %s -x c &#8211; -o %s&quot;</span>, GCC_FLAGS, tmp_path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// execute gcc command, write out the code<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp = <span style="color:#003369;">popen</span>(command_buffer, <span style="color:#760f15;">&quot;w&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fwrite</span>(code_buffer, <span style="color:#0000ff;">1</span>, <span style="color:#003369;">strlen</span>(code_buffer), fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">fprintf</span>(fp, <span style="color:#760f15;">&quot;\n&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// pclose waits for gcc to terminate (fclose/close do NOT thus compilation will sometimes not finish prior to the dlopen)<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">pclose</span>(fp);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">void</span> *ptr = <span style="color:#881350;">NULL</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// open the just-compiled dynamic library<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>((lib = <span style="color:#003369;">dlopen</span>(tmp_path, RTLD_NOW|RTLD_LOCAL)) == <span style="color:#881350;">NULL</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">puts</span>(<span style="color:#003369;">dlerror</span>());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// get the function pointer<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">else</span> <span style="color:#881350;">if</span><span style="color:#003369;"> </span>((ptr = <span style="color:#003369;">dlsym</span>(lib, function_name)) == <span style="color:#881350;">NULL</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">puts</span>(<span style="color:#003369;">dlerror</span>());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// execute it<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">if</span><span style="color:#003369;"> </span>(ptr != <span style="color:#881350;">NULL</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func_return_double *func = (func_return_double*)ptr;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = (*func)(result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// print the result<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">printf</span>(<span style="color:#760f15;">&quot;=&gt; %.*lf\n&quot;</span>, (result/((<span style="color:#881350;">int</span>)result)&gt;<span style="color:#0000ff;">1.0</span>)?<span style="color:#0000ff;">5</span>:<span style="color:#0000ff;">0</span>, result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#236e25;">// clean up: close the library, delete the temp file<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">dlclose</span>(lib);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#003369;">unlink</span>(tmp_path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#881350;">return</span> <span style="color:#0000ff;">0</span>;<br />
}
</div>
<p>Thanks to jbert on Reddit for the initial code and inspiration.</p>
<p>If only I had known about this back when The Daily WTF has having their [OMG WTF](http://omg.thedailywtf.com/) crazy calculator programming contest&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://tlrobinson.net/blog/2007/12/presenting-gccalc-a-horribly-awesome-abuse-of-gcc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

