Click here to Skip to main content
Email Password   helpLost your password?

Sample Image - Mandelbrot_Obfuscation.jpg

Introduction

Code that generates the Mandelbrot set is a favorite target of obfustactionists (obfuscate: v. to make obscure). The main reasons for this are probably: 1) images of the Mandelbrot set are familar to most people, even if they don't know anything about computers, mathematics or fractals, and 2) the code required to generate the images is very simple.

The Mandelbrot Set

First, a quick introduction to the Mandelbrot Set and the theory behind it. The Mandelbrot Set is a set of complex numbers that exhibit an interesting behavior when run through a simple formula. When this formula is applied repeatedly (with the result from one calculation used as the input to the next calculation), numbers within the Mandelbrot set will, no matter how many times you apply the formula, not get farther than a certain distance from 0,0i (the origin of the complex plane). Numbers not in the Set will, after some number of iterations, exceed that magic distance. The numbers that "escape" are not in the Set, but they are the interesting values when making images. The basic technique is to use the number of iterations required to make the number escape as an index into a color table and to color the values inside the set as plain black.

The formula

zi = z2 + z0
In the formula, z0 is the initial value and zi is the value at iteration i. The "escape" radius is 2: if zi ever exceeds a distance of 2 from the origin, that point is considered to be outside the set. Don't let the complex numbers scare you. The math required to do this is very simple and you don't even need to understand it to use it.

How to make a picture

First you decide on an area of the complex plane that you want to investigate. Pick a rectangular area of the plane, say from (-2.3, -1i) to (.65, .95i). Then decide on the number of points in that area that you want to evaluate: essentially, the size of the output image. Then, for each point in the output image, find the corresponding point on the imaginary plane and run it through the formula until the value escapes, or you decide you've done enough iterations. Then when you've stopped calculating, you set the output pixel to a color based on the number of iterations it took the value to escape (the final i), if it escaped at all.

The code we'll start with

#include "stdafx.h"

#include <conio.h>

void main()
{
    // output size

    int rows = 40, cols = 60;

    // number of iterations before we quit

    int maxiter = 255;

    // size and position of the rect on the imaginary plane

    double fViewRectReal = -2.3, fViewRectImg = -1.0;
    double fMagLevel = 0.05;

    for (int y=0; y < rows; y++)
    {
        // imaginary component of "c"

        double fCImg = fViewRectImg + y * fMagLevel;
        
        for (int x=0; x < cols; x++)
        {
            // real component of "c"

            double fCReal = fViewRectReal + x * fMagLevel;
            double fZReal = fCReal;
            double fZImg = fCImg;
            
            // apply the formula...

            bool bInside = true;
            int n;
            for (n=0; n < maxiter; n++)
            {
                double fZRealSquared = fZReal * fZReal;
                double fZImgSquared = fZImg * fZImg;

                // have we escaped?

                if (fZRealSquared + fZImgSquared > 4)
                {
                    bInside = false;
                    break;
                }

                // z = z^2 + c

                fZImg = 2 * fZReal * fZImg + fCImg;
                fZReal = fZRealSquared - fZImgSquared + fCReal;
            }

            // in this code, we only care about inside vs. outside.

            // in a real renderer, you would care about the value of "n"

            // when choosing your output color.

            if (bInside)
            {
                putchar(' ');
            }
            else
            {
                putchar('+');
            }
        }
        putchar(10);
    }

    while (!kbhit());
}

A console app???

The first thing you'll notice is that this is not a Windows app, it's a plain C app.
Q: Why?
A: There's no point in obfuscating a whole MFC app. There is too much code required for even the simplest dialog app. But a console app can be literally a single function.

Obfuscation

The idea behind obfuscation is to cause the person looking at the code it to wonder how the code can possibly do what it does. There are many ways to approach this. The basic method is to remove any hints in the code as to the algorithm, the data structures, the flow or the purpose - make the code as hard to follow as possible. This is what I'll show here. Another level of obfuscation is to change the actual algorithm used so that it's impossible to tell what the program is doing, even if the code is perfectly formatted and even if it's commented. I'll only approach this level here.

Get to it already

The first thing I'll do is a little optimization. Notice that we're looping over the output pixels with the x and y loops, and calculating c (c is just zi from the formula - the initial input) based on x and y. Also notice that x and y are only used to do two things: count off rows and columns, and calculate the real and imaginary parts of c. And, to top it off, the distance between the one value for c and the next is constant in both dimensions: double fCImg = fViewRectImg + y * fMagLevel;. So????

This means we can get rid of x and y and simply loop over the real and imaginary parts of c. x and y were really only there to make things easy to understand, and that's exactly what we're trying to avoid. So, for the y loop, instead of this:

for (int y=0; y < rows; y++)
{
    // imaginary component of "c"

    double fCImg = fViewRectImg + y * fMagLevel;
...we get this:
for (double fCImg = fViewRectImg; 
     fCImg < fViewRectImg + rows * fMagLevel; fCImg+=fMagLevel)
{
Well, that's certainly hard to read, but it's too long and does too much unnecessary calculation. everything in there is a constant. So, let's get rid of the math.
for (double fCImg = -1; fCImg < 1; fCImg+=fMagLevel)
{
And now we don't need the fViewRectImg variable anymore, either. Likewise, for the x loop, we go from:
for (int x=0; x < cols; x++)
{
    fCReal = fViewRectReal + x * fMagLevel;
    ....
to
for (double fCReal =-2.3; fCReal < .7; fCReal+=fMagLevel)
{ 
    ...
And, now we can get rid of fViewRectReal and the "rows" and "cols" variables, too. And while we're at it, let's get rid of fMagLevel too. It's just a constant. One more simple thing, let's move all of the variable declarations to the top of the function, out of the loops. And, let's put all of the double's on the same line. This will cut down the number of times we see the keyword "double". So, we've removed seven variables and two lines of code: no big deal. The code is still readable, though it's somewhat less flexible - before you could change the number of rows and columns or the level of magnification, or the view rect pretty easily. Now, those variables are all combined - we're increasing the specialization of the code - and that's a good thing, for obfuscation.
void main()
{
    int maxiter = 255;
    double fZReal, fZImg, fZRealSquared, fZImgSquared, fCReal, fCImg;
    bool bInside;
    int n;

    for (fCImg = -1; fCImg < 1; fCImg+=.05)
    {
        for (fCReal =-2.3; fCReal < .7; fCReal+=.05)
        {
            fZReal = fCReal;
            fZImg = fCImg;
            
            bInside = true;
            for (n=0; n < maxiter; n++)
            {
                fZRealSquared = fZReal * fZReal;
                fZImgSquared = fZImg * fZImg;
                if (fZRealSquared + fZImgSquared > 4)
                {
                    bInside = false;
                    break;
                }
                
                fZImg = 2 * fZReal * fZImg + fCImg;
                fZReal = fZRealSquared - fZImgSquared + fCReal;
            }

            if (bInside)
            {
                putchar(' ');
            }
            else
            {
                putchar('+');
            }
        }
        putchar(10);
    }

    while (!kbhit());
}

The first trick

The maxiter variable holds the maximum number of iterations we'll allow before bailing out of the calculation section: 255. That number should feel important to you; it's the number of values a char can hold. So, we can use that special property of a char in a tricky way. Get rid of the variable 'n'. Add a variable at the top of the function called "iter" of type char. Take the inner loop:
for (n=0; n < maxiter; n++)
{
and replace it with
for (iter=1; iter; iter++)
{
This is counting on the fact that, when iter reaches -1, adding one to it will cause it to go to zero. How does it get to -1 from +1 ? By going up to 127, then flipping to -128 and counting up to 0. And because for loops work by exiting when the middle expression turns to zero, our loop still works like we want, even though the path iter takes to get there is not exactly what you see in counters. It's ugly and non-intuitive and that's what we want.

Trick two?

Next, look at the if (bInside) section. The only time bInside is true is if we go through all 255 iterations of the loop; otherwise, we bailed early. Well, if we went through all 255 iterations, iter is going to be zero. So, bInside is redundant. We could replace if (bInside) with if (!iter), but that doesn't buy us very much. Instead, lets make use of my favorite C operator, the "?", or "in-line if". So, get rid of bInside and replace that whole if (bInside)...else section with this: putchar(iter ? '+' : ' ');. The "?" operator is awesome.

Trick three

One nice feature of the for loop is that the middle expression, the one that decides when to stop the loop, can be as complex as you want, as long as it can be evaluated as an integer or boolean expression. That means we can take the if (fZRealSquared + fZImgSquared > 4) test out of the body of the inner loop and put it in the middle expression of the controlling for expression. So, the inner loop goes from:
            for (iter=1; iter; iter++)
            {
                fZRealSquared = fZReal * fZReal;
                fZImgSquared = fZImg * fZImg;
                if (fZRealSquared + fZImgSquared > 4)
                {
                    break;
                }
                
                fZImg = 2 * fZReal * fZImg + fCImg;
                fZReal = fZRealSquared - fZImgSquared + fCReal;
            }
to
            fZRealSquared = fZImgSquared = 0;
            for (iter=1; iter && (fZRealSquared + fZImgSquared < 4); iter++)
            {
                fZRealSquared = fZReal * fZReal;
                fZImgSquared = fZImg * fZImg;
                fZImg = 2 * fZReal * fZImg + fCImg;
                fZReal = fZRealSquared - fZImgSquared + fCReal;
            }

We have to initialize fZImgSquared and fZRealSquared before we test them. In the original version, the test was done after the values were calculated. Now we'll just set them to zero, which guarantees they'll get into the loop at least once. Note that this will cause the value of iter to be off by one in many cases. But, we don't care about the actual value here - we only care if it takes less than 255 iterations to escape. This trick won't effect the overall result in any meaningful way, and anyway, we'll fix it in a minute.

Even better, because the middle expression in a for loop is evaluated each time through the loop, you can actually get rid of the third expression in the loop, the place where you normally increment the counter, and move the increment to the middle section:

for (iter=1; ++iter && (fZRealSquared + fZImgSquared < 4);)
{
Ahhh... now it's getting ugly.

Even better than that, let's abuse the equals operator, too! As you may know, when you assign something in C, the assignment actually produces a return value: a = 3 + 5; returns, in a sense, "8". Normally we just let that return value vanish. But, we can use it. Here's our inner loop:

for (iter=1; ++iter && (fZRealSquared + fZImgSquared < 4);)
{
    fZRealSquared = fZReal * fZReal;
    fZImgSquared = fZImg * fZImg;
    fZImg = 2 * fZReal * fZImg + fCImg;
    fZReal = fZRealSquared - fZImgSquared + fCReal;
}
Let's move the first two calculations into the middle part of the for expression:
for (iter=1; ++iter && ((fZRealSquared = fZReal * fZReal) + 
                        (fZImgSquared = fZImg * fZImg) < 4);)
{
    fZImg = 2 * fZReal * fZImg + fCImg;
    fZReal = fZRealSquared - fZImgSquared + fCReal;
}

Increment? nah

Hmmm... Now, what can we do with the third part of that for expression? It looks so empty. I know, let's put the rest of the inner loop in there! We can use the magic "comma" operator to combine the two statements. The comma operator is similar to the semicolon, but with some special side-effects. None of the special side-effects are interesting here, we just want to put two expressions into the for statement, where a semicolon wouldn't work. And while we're at it, let's put the fZRealSquared = fZImgSquared = 0; line from immediately before the for expression into the first part:

So, here's our inner loop now, with a semi-colon at the end because there's no loop body.

for (fZRealSquared = fZImgSquared = 0, iter=1; 
    ++iter && ((fZRealSquared = fZReal * fZReal) + 
               (fZImgSquared = fZImg * fZImg) < 4);
    fZImg = 2 * fZReal * fZImg + fCImg, 
                fZReal = fZRealSquared - fZImgSquared + fCReal);

How's that for ugly? I love it. Here's the whole thing:
void main()
{
    char iter;
    double fZReal, fZImg, fZRealSquared, fZImgSquared, fCImg, fCReal ;

    for (fCImg = -1; fCImg < 1; fCImg+=.05)
    {
        for (fCReal =-2.3; fCReal < .7; fCReal+=.05)
        {
            fZReal = fCReal;
            fZImg = fCImg;

            for (fZRealSquared = fZImgSquared = 0, iter=1; 
                ++iter && ((fZRealSquared = fZReal * fZReal) + 
                           (fZImgSquared = fZImg * fZImg) < 4);
                fZImg = 2 * fZReal * fZImg + 
                   fCImg, fZReal = fZRealSquared - fZImgSquared + fCReal);

                putchar(iter ? '+' : ' ');
        }
        putchar(10);
    }

    while (!kbhit());
}

More of that!

It's starting to look like we can put anything we want into a for expression. Let's see how far we can take that idea. The first putchar call looks like it's part of the inner loop, but it's not. The inner loop has no body - everything happens inside the for statement itself and the loop body is empty (note the semicolon after the final parenthesis on that for(...)). So, the putchar actually belongs to the middle loop. Let's make that more obvious by moving it into the middle for expression:
for (fCReal =-2.3; fCReal < .7; fCReal+=.05, putchar(iter ? '+' : ' '))
{
Let's move the fZReal and fZImg assignments in there, too.
for (fCReal =-2.3; fCReal < .7; 
     fCReal+=.05, putchar(iter ? '+' : ' '), 
     fZReal = fCReal, fZImg = fCImg)
{
OK, let's put the other putchar call into its for loop, too:
for (fCImg = -1; fCImg < 1; fCImg+=.05, putchar(10))
And here's the whole thing:
void main()
{
    char iter;
    double fZReal, fZImg, fZRealSquared, fZImgSquared, fCImg, fCReal;

    for (fCImg = -1; fCImg < 1; fCImg+=.05, putchar(10))
    {
        for (fCReal =-2.3; fCReal < .7; fCReal+=.05, 
             putchar(iter ? '+' : ' '), fZReal = fCReal, fZImg = fCImg)
        {
            for (fZRealSquared = fZImgSquared = 0, iter=1; 
                ++iter && ((fZRealSquared = fZReal * fZReal) + 
                           (fZImgSquared = fZImg * fZImg) < 4);
                fZImg = 2 * fZReal * fZImg + fCImg, 
                        fZReal = fZRealSquared - fZImgSquared + fCReal);
        }
        
    }

    while (!kbhit());
}

I have no body!

C is clever. If you have a controlling statement like an if, while or for that only has a single statement in its body, you don't need curly braces. So, we can get rid of the curly braces in the other for loops, too.
void main()
{
    char iter;
    double fZReal, fZImg, fZRealSquared, fZImgSquared, fCImg, fCReal;

    for (fCImg = -1; fCImg < 1; fCImg+=.05, putchar(10))
        for (fCReal =-2.3; fCReal < .7; fCReal+=.05, 
              putchar(iter ? '+' : ' '), fZReal = fCReal, fZImg = fCImg)
            for (fZRealSquared = fZImgSquared = 0, iter=1; 
                ++iter && ((fZRealSquared = fZReal * fZReal) + 
                           (fZImgSquared = fZImg * fZImg) < 4);
                fZImg = 2 * fZReal * fZImg + fCImg, 
                        fZReal = fZRealSquared - fZImgSquared + fCReal);

    while (!kbhit());
}
Now in my opinion, that's awesome.

Final tweaks

Let's change this line:
for (fZRealSquared = fZImgSquared = 0, iter=1; 
to this:
for (fZRealSquared = fZImgSquared = (iter=1)--;
And just for fun, let's take that "fZRealSquared =" expression and put it in the final part of the preceding for expression. It's nice to start a for loop with an empty initialization section, once in a while. And let's change the second putchar, to this putchar(iter ? '?' : ':'). The repetition of the ? and the : make it hard to read. That's nice.

And finally...

Let's replace all the long variable names with single letters - like "O", "l", "i", "o", "I" and "_", get rid of any extra white space and lose the while(kbhit()) line:
void main()
{
   double O,x,o,I,l,i;char _;for(l=-1;l<1;l+=.05,
   putchar(10))for(i=-2.3;i<.7;i+=.05,putchar(_?
   '?':':'),O=i,x=l,o=I=(_=1)--)for(;++_&&((o=O*
   O)+(I=x*x)<4);x=2*O*x+l,O=o-I+i);
}

Conclusion

We took a 1030+ character, 60 line program and reduced it to 7 lines and 182 characters, not bad. But most importantly, we reduced it to a nearly incomprehensible stream of ASCII garbage. Mission accomplished.

P.S.

If you'd like to see some more fractals, look here.

P.P.S.

After some more tinkering, I managed to get it down to 156 characters. Here's the result:
main()
{
   float C,l,c,o,O,I=-20;char _;for(;I++<20;puts(""))
   for(O=-46;O<14;putchar(_?42:32),O++)for(C=l=_=0;o
   =l*l,c=C*C,l=2*C*l+I/20,C=c-o+O/20,o+c<4&&++_;);
}

What's different?

First, the obvious: The other characters were much harder to come by and involved removing some redundant initializations, and changing the outer two loops to increment by one instead of by a fraction (forcing two "/20"s later on, but saving two characters overall).

For something completely different...

As was pointed out in a comment, the fact that there are still three "for" loops makes deciphering the code somewhat easy. So, though I'm not going to explain how I did it (maybe in another article...), here's a version of the program that uses only one for loop:
#include "stdio.h"

main()
{
    int b=0,c=0,q=60,_=q;for(float i=-20,o,O=0,l=0,j,p;j=O*O,p=l*l,
    (!_--|(j+p>4)?fputc(b?q+(_/3):10,(i+=!b,p=j=O=l=0,c++,stdout)),
    _=q:l=2*O*l+i/20,O=j-p+o),b=c%q,c<2400;o=-2+b*.05);
}
The cool things about this one are: Cheers!
-c
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralConfused
ComaWhite86
18:00 1 Apr '09  
Why do you wanna obfuscate C++ code or even C when its obfuscated as it is as normal? OBfuscation for C++ is dumb in my opinion. It's not like you can see under the hood like C# or VB.NET. So why bother?
GeneralRe: Confused
Chris Losinger
18:05 1 Apr '09  
ComaWhite86 wrote:
It's not like you can see under the hood like C# or VB.NET.

Confused

you're kidding, right ?

ComaWhite86 wrote:
So why bother

because it's fun.


GeneralRe: Confused
ComaWhite86
18:56 1 Apr '09  
Well if you use a decent decompiler. And remove all the debugging symbols, optimise it and what not. Good luck. It's fun more along the lines of redundancy. Serves no single purpose. You can easily hide the implementation of the code in the .cpp files >.>
GeneralMy vote of 1
ComaWhite86
17:58 1 Apr '09  
why the hell would you want to obfuscate C code. It's already obfuscated enough as it is.
GeneralLive long and prosper!
Jim Crafton
10:51 29 Nov '07  
I salute you sir! Smile And humbly raise my glass to you! Beer

¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF! VCF Blog

GeneralNIce
bugDanny
9:53 30 Sep '05  
I had one thought though. At a point in your article, you took:
if (fZRealSquared + fZImgSquared > 4)
{
break;
}
and put it in the the loop, like this
for (iter=1; iter && (fZRealSquared + fZImgSquared < 4); iter++)
{ }
Now, i > 4 is not the same as !(i < 4) , because what if i in my hypothetical is 4. Then i would not be greater than 4, as in the first point, but it would not be less than 4, as in the second point. Put simply, didn't you forget the little = sign when making that move. Should it have been, (fZRealSquared + fZImgSquared <= 4) when you put it in the loop.


Danny

The stupidity of others amazes me!
GeneralThis has been done before
Frans Faase
2:33 1 Oct '02  
Very interesting discussion, but this has been done before. Please
look at http://home.planet.nl/~faase009/Signindex.html and search
for Mandelbrot.


GeneralRe: This has been done before
Chris Losinger
4:57 1 Oct '02  
Frans Faase wrote: but this has been done before
of course. i never claimed to be the first. there are hudreds of obfuscated mandelbrot demos out there. in fact, if you read my article, the first sentence acknowledges this:

"Code that generates the Mandelbrot set is a favorite target of obfustactionists..."

but... i don't see any other codeproject articles on it.

-c


All you have to do is tell the people they are being attacked, and denounce the opposition for lack of patriotism and exposing the country to danger.
-- Herman Goering, on how to control the public
GeneralC++ Version
moredip
9:17 9 Jul '02  
If you were comfortable creating a C++ version of the code you could replace { with <%, } with %>, etc. For more info see 'C.3.1 Restricted Character Sets' in The C++ Language (3rd Edition).

I /think/ the following works...

#include "stdio.h"
main()
<% int b=0,c=0,q=60,_=q;for(float i=-20,o,O=0,l=0,j,p;j=O*O,p=l*l,??/
(not_--|(j+p>4)?fputc(b?q+(_/3):10,(i+=!b,
p=j=O=l=0,c++,stdout)),_=q:l=2*O*l+i/20,O=j-p+o),\
b=c%q,c<2400;o=-2+b*.05); ??>

Pete
GeneralSome more obfuscated fractal code...
Anonymous
11:03 12 May '02  
Hi,

I wrote this some time ago, it's 192 bytes long - so not as short as is possible by a long shot - but it does draw a nice mandelbrot Blush ) It assumes
the column width of the console is 80 chars wide and draws a fractal 40 chars high:
#include <stdio.h>

float O,Q,l,L,U,_,o,I,i;main(){for(i=L=_=-2.25,
o=U=L+1;26>++l&&_*_<=4-o*o||(putchar(26==l?32:l
+97),_=L,o=U,l=0)||80>++O&&(L+=.0375)||(O=0,L=i
,U+=.0625,++Q<40);I=_,_=_*_-o*o+L,o=U+I*2*o);};

GeneralANSI C version
Paul Mutton
0:50 12 May '02  
Tried to get it to work on UNIX, but while it compiles with
Visual C, it doesn't seem to compile with gcc.

Here's a ANSI C version for those who want to try it out
on UNIX and other platforms:-

#include <stdio.h>
main()
{
      int b=0,c=0,q=60,_=q;float i=-20,o,O=0,l=0,j,p;for(;j=O*O,p=l*l,
      (!_--|(j+p>4)?fputc(b?q+(_/3):10,(i+=!b,p=j=O=l=0,c++,stdout)),
      _=q:(l=2*O*l+i/20),O=j-p+o),b=c%q,c<2400;o=-2+b*.05);
}



http://www.jibble.org/
GeneralRe: ANSI C version
Anonymous
10:47 15 May '02  
Yes, the :? operator has a higher precedence than assignment.

But it's ok, because you can shorten it in other places:

#include <stdio.h>
main()
{int O=0,l=60,i=l*40,I=l;for(float Z=-20,o,T
=0,C=0,Q,L;Q=T*T,L=C*C,(!I--|(Q+L >4) ?fputc
(O?l+I%10:10,(Z+=!O,T=C=0,--i,stdout)),I=l:(
C=2*T*C+Z/20,T=Q-L+o)),i;o=-2+O*.05 )O=i%l;}

I think in this case it would have been better to use lO and IO instead of Q and L, but I wanted to keep it short.
GeneralNice and Interesting
yarp
11:17 10 May '02  
I love fractals. Your article is a good example of demistificating factal coding if read in reverse order.
So I'll read it backward Wink )

Yarp
GeneralToo many loops
Anonymous
22:02 9 May '02  
You see, the main problem I have with this is that you are still using three easy to identify loops. A better solution, which I found at http://www.everything2.com/index.pl?node=a+cool+short+c+program is:

#include
float o=0.075,h=1.5,T,r,O,l,I;
int _,L=80,s=3200;main(){for(;
s%L||(h-=o,T= -2),s;4 -(r=O*O)
<(l=I*I)|++_==L&&write(1,(--s%
L?_<L?--_%6:6:7)+"123456 \n",1
)&&(O=I=l=_=r=0,T+=o/2))O=I*2*
O+h,I=l+T-r;}


GeneralRe: Too many loops
Chris Losinger
7:59 10 May '02  
ok. i love a challenge..

here's my one-loop version:

#include "stdio.h"

main(){int b=0,c=0,q=60,n=q;for(float i
=-20,o,O=0,l=0,j,p;j=O*O,p=l*l,(!n--|(j
+p>4)?fputc(b?'0'+(n&10):10,(i+=!b,p=j=
O=l=0,c++,stdout)),n=q:l=2*O*l+i/20,O=j
-p+o),b=c%q,c<2400;o=-2+b*.05);}

IMHO, this goes one step farther than the one you posted above. in this, everything is in the for loop. the one above actually has a statement controlled by the for loop - how awful! Smile and, mine is 2 characters shorter, hooray!

also, unlike the two in the article, this one uses the number of iterations to choose among a set of different output chars, so you can see (like the one you posted) the countours within the set.

i love this stuff.

-c


There ain't no second chance
Against the thing with the forty eyes

GeneralRe: Too many loops
Anonymous
10:58 12 May '02  
Hi,

Just a little thought. It is my understanding that globally declared vars will be initialised to 0. Hence instead of:

main(){int b=0,c=0,q=60,n=q;for(

You could write:

int b,c,q=60,n=q;main(){for(

And save a few chars ;o) Then again I could be wrong!

GeneralRe: Too many loops
Chris Losinger
11:02 12 May '02  
Anonymous wrote:
It is my understanding that globally declared vars will be initialised to 0.
only in debug builds.

-c


There ain't no second chance
Against the thing with the forty eyes

GeneralRe: Too many loops
Anonymous
11:06 12 May '02  
Chris Losinger wrote:
only in debug builds.
I guess my little bit of code I just posted will only work properly when compiled as a debug build then ;o)

You learn something new everyday!

Thanks.

GeneralRe: Too many loops
Jim Barry
11:33 28 May '02  
I'm surprised at you Chris. Objects with static storage duration are implicitly initialised to zero if they are not explicitly initialised. Of course. In C or C++. Debug or release. Also "void main()" is not a valid form of main; the return type should be int.

- Jim

GeneralRe: Too many loops
Chris Losinger
10:03 31 May '02  
Jim Barry wrote:
Objects with static storage duration are implicitly initialised to zero if they are not explicitly initialised.
nobody marked anything as "static". if you're saying that "static" variables are initalized, then that's great, but nobody here is using them. a global variable is not exactly a static variable.

Jim Barry wrote:
Also "void main()" is not a valid form of main; the return type should be int.
you'll have to take that up with MS, i guess. VC compiles it and Windows runs it, happily.

-c



Cheap oil. It's worth it!
GeneralRe: Too many loops
Jim Barry
13:05 31 May '02  
Chris Losinger wrote:
nobody marked anything as "static". if you're saying that "static" variables are initalized, then that's great, but nobody here is using them. a global variable is not exactly a static variable.
No, that's not what I am saying. There are three kinds of storage duration: static, automatic and (in C++) dynamic. Automatic storage duration corresponds to local objects; dynamic storage duration corresponds to objects created with 'new'. Objects that are neither automatic nor dynamic have static storage duration, and that certainly includes global variables.

Chris Losinger wrote:
you'll have to take that up with MS, i guess. VC compiles it and Windows runs it, happily.
Yes, I know, but that doesn't make it standard C or C++.

- Jim
GeneralRe: Too many loops
Anonymous
7:21 23 Jul '02  
void main is standard C. Just not on hosted systems.
GeneralRe: Too many loops
Jim Barry
13:39 23 Jul '02  
Anonymous wrote:
void main is standard C. Just not on hosted systems.
Er yes (sort of), but the code in the article requires a hosted implementation (it uses putchar).

- Jim

Jim Barry <jim@mvps.org>
MVP for Windows SDK
GeneralRe: Too many loops
Chris Losinger
14:13 23 Jul '02  
the last one, the one that fixes the "too many loops" problem (hence this thread) uses fputc, if that matters.

-c


To explain Donald Knuth's relevance to computing is like explaining Paul's relevance to the Catholic Church. He isn't God, he isn't the Son of God, but he was sent by God to explain God to the masses.
   /. #3848917

GeneralRe: Too many loops
Jim Barry
14:41 23 Jul '02  
Chris Losinger wrote:
> the last one, the one that fixes the "too many loops"
> problem (hence this thread) uses fputc, if that matters.

I'm afraid not. Programs for freestanding (non-hosted) implementations are restricted to facilities from <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, and <stdint.h>. Both putchar and fputc are <iostream.h> facilities.

- Jim

Jim Barry [WinSDK MVP]


Last Updated 21 May 2002 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010