Written Program Size: A Comparison of C vs. Assembly

joeyd999

Joined Jun 6, 2011
6,334
A very excellent and valid point Joey. I assume you prefer to use assembly for all of your work?
For MCU projects, yes. It'd be kinda silly to write a PC app in asm.

One other point to consider:

When you're developing PC apps, you have easy and inexpensive opportunities to update your user's code when bugs eventually arise (whether they be from your code, or updates to the libraries you link in).

On the other hand, most times a user of a device with defective code must send the device back to the mfgr for repair. First impressions are everything. I always try to ship bug-less code, and am most times successful. It'd be difficult for me to do this if I was dependent upon someone else for the implementation.
 
If buying the full version of hi tech c is out then just use a bigger memory pic chip.
PIC's are cheap enough.

Its only if you are going to start selling loads of PICs that it might become an issue.
 

Markd77

Joined Sep 7, 2009
2,806
Is there any way to see which part of the C code is responsible for the sections of assembler?
That would make it easier to work out which bits are adding unnecessary bloat.
I'm an assembler person, but that disassembly makes hard reading.
 

t06afre

Joined May 11, 2009
5,934
Is there any way to see which part of the C code is responsible for the sections of assembler?
That would make it easier to work out which bits are adding unnecessary bloat.
I'm an assembler person, but that disassembly makes hard reading.
@To the OP
The solution to this, is quite simple. In MPLAB compile the code. Then open a disasmbly window (View in the toolbar). Copy and paste from this window. And use code tags sp the formating do not get messed up. The leftmost numbers refer to line number in the C code. Here is a snipet from some code I am working on now.
Rich (BB code):
37:                void lcd_write(unsigned char c)
38:                {
39:                 __delay_us(40);
   7AB    300D     MOVLW 0xd
   7AC    00F0     MOVWF 0x70
   7AD    0BF0     DECFSZ 0x70, F
   7AE    2FAD     GOTO 0x7ad
40:                 LCD_DATA = ( c & 0xF0 );
   7AF    0872     MOVF 0x72, W
   7B0    39F0     ANDLW 0xf0
   7B1    1283     BCF 0x3, 0x5
   7B2    1303     BCF 0x3, 0x6
   7B3    0086     MOVWF 0x6
41:                 LCD_STROBE();
   7B4    1586     BSF 0x6, 0x3
   7B5    1186     BCF 0x6, 0x3
42:                        LCD_DATA = ((c >> 4) | (c << 4)& 0xF0);
   7B6    0872     MOVF 0x72, W
   7B7    00F0     MOVWF 0x70
   7B8    0E70     SWAPF 0x70, W
   7B9    39F0     ANDLW 0xf0
   7BA    00F0     MOVWF 0x70
   7BB    39F0     ANDLW 0xf0
   7BC    00F1     MOVWF 0x71
   7BD    0E72     SWAPF 0x72, W
   7BE    390F     ANDLW 0xf
   7BF    0471     IORWF 0x71, W
   7C0    0086     MOVWF 0x6
 

John P

Joined Oct 14, 2008
2,063
My ancient version of the CCS compiler produces a .LST file, which shows C source and assembly interspersed. It's useful to take a quick look through the file and see which lines of C produce really outrageous amounts of assembly. Sometimes just a simple rearrangement of the C code can make the output much more compact, without any need to understand the assembly code in detail.

In general though, the philosophy of using a compiler is that you also get a processor with enough memory and computing power to allow for the inefficiency of the code. The extra hardware cost is peanuts, but the time saved in writing and debugging--especially if someone has to come back and make changes later--is much more valuable.
 

Markd77

Joined Sep 7, 2009
2,806
If I understand the C right, there's some good bloat in T06AFREs example too.
I think this:
Rich (BB code):
42:                        LCD_DATA = ((c >> 4) | (c << 4)& 0xF0);
   7B6    0872     MOVF 0x72, W
   7B7    00F0     MOVWF 0x70
   7B8    0E70     SWAPF 0x70, W
   7B9    39F0     ANDLW 0xf0
   7BA    00F0     MOVWF 0x70
   7BB    39F0     ANDLW 0xf0
   7BC    00F1     MOVWF 0x71
   7BD    0E72     SWAPF 0x72, W
   7BE    390F     ANDLW 0xf
   7BF    0471     IORWF 0x71, W
   7C0    0086     MOVWF 0x6
could be shortened to:
Rich (BB code):
42:                        LCD_DATA = ((c >> 4) | (c << 4)& 0xF0);
SWAPF 0x72, W
ANDLW 0xf0
MOVWF 0x6
A 72% reduction in code.
 

thatoneguy

Joined Feb 19, 2009
6,359
Go to options and turn optimization to highest and post the code.

Try only the demo version of the C compiler you are using and see what it comes out with.

I know the CLRWDT are gone in the registered version, .hex shrunk about 50% from what the demo version made if max optimizations are enabled.

I usually write it in C, and if the compiler made statments for a "general case" of handling the data, as it is supposed to do, I'll change out a function for inline assembly, eliminating that issue.

never use sprintf or printf if you can avoid it.
 

AlexR

Joined Jan 16, 2008
732
Just out of interest I converted your C code to SourceBoostC
Rich (BB code):
//
//    6-LIGHT, 4-WAY INTERSECTION TRAFFIC CONTROL SIGNAL
//    RYAN GOFF
//    JAN-14-2011
//    PIC16F628A
//    HIGH-TECH C COMPILER, MPLAB IDE
//
//    THIS PROGRAM IS FOR A 6-LIGHT INTERSECTION TRAFFIC CONTROL
//    SIGNAL WHERE BOTH THE MAIN TRAFFIC LANES (MAIN) AND SECONDARY
//    TRAFFIC LANES (SDRY) HAVE A SINGLE SET OF RED, YELLOW, GREEN
//    LIGHTS WHICH WILL CYCLE TO SAFELY CONTROL TRAFFIC WHILE
//    OPERATED IN THE NORMAL CYCLE.  THE SIGNAL ALSO HAS 2 NIGHT-
//    MODE CYCLES WHERE MAIN TRAFFIC LANES RECEIVE A FLASHING YELLOW
//    SIGNAL WHILE SECONDARY TRAFFIC LANES RECEIVE A FLASHING RED
//    SIGNAL, OR ALL TRAFFIC LANES RECEIVE A FLASHING RED SIGNAL.
//    SELECTION OF EITHER OF THESE NIGHT-MODE CYCLES IS DEPENDENT ON
//    THE POSITION OF A SINGLE ON-OFF-ON SWITCH WHICH WILL INPUT
//    HIGH TO porta.0 OR porta.1.  WHEN BOTH INPUTS ARE LOW, NORMAL CYCLE
//    OPERATION RESULTS.  THE SIGNAL IS PROGRAMMED TO NEVER ALLOW AN
//    UNSAFE SIGNAL CONDITION, THEREFORE, TRANSITION FROM NORMAL
//    OPERATION TO A NIGHT-MODE CYCLE OR VISE-VERSA IS NOT
//    INSTANTANEOUS, AND WILL OCCUR ONLY AT THE PROGRAMMED SAFE
//    POINT.
//
/****************************************************************/

// CONFIGURATION

#include <system.h>
#pragma CLOCK_FREQ 48000
#pragma DATA _CONFIG, _CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT

//    INTERNAL 48KHz CLOCK, PWRT, NO PROTECTION

/***************************************************************/




/***************************************************************/

void main()
{
    pcon.OSCF = 0;               // LOW POWER 48KHZ INTOSC
    cmcon = 0x07;           // COMPARATORS OFF
    trisa = 0x03;           // porta.0 AND porta.1 INPUT, OTHERS OUTPUT
    trisb = 0;               // ALL PORT B ARE OUTPUTS              //ALL PORT B ARE OUTPUTS

    while(1)
    {
        while (porta.0==1)            //WHILE INPUT AT porta.0, NMRR
        {
            portb=0x08;            //RB3 ON, SECONDARY RED, ALL OTHERS OFF
            delay_ms(250);
            delay_ms(250);
            portb=0x01;            //RB0 ON, MAIN RED, ALL OTHERS OFF
     
        }
        while (porta.1==1)            //WHILE INPUT AT porta.1, NMRY
        {
            portb=0x08;
            delay_ms(250);
            delay_ms(250);            //RB3 ON, SECONDARY RED, ALL OTHERS OFF
            portb=0x02;            //RB1 ON, MAIN YELLOW, ALL OTHERS OFF
            delay_ms(250);
            delay_ms(250);  
        }
        if ((porta.0!=1)&&(porta.1!=1))    //porta.0 AND porta.1 NO INPUT
        {
            portb=0x09;            //RB0 ON, RB3 ON, MAIN RED, SDRY RED
            delay_s(3);    //LOOP 1 SECOND DELAY 3 TIMES, 3-SECOND DELAY
            portb=0x0C;            //RB2 ON, RB3 ON, MAIN GREEN, SDRY RED
            delay_s(20);    //LOOP 1 SECOND DELAY 20 TIMES, 20-SECOND DELAY
            portb=0x0A;            //RB1 ON, RB3 ON, MAIN YELLOW, SDRY RED
            delay_s(4);    //LOOP 1 SECOND DELAY 4 TIMES, 4-SECOND DELAY
            portb=0x09;            //RB0 ON, RB3 ON, MAIN RED, SDRY RED
            delay_s(3);    //LOOP 1 SECOND DELAY 3 TIMES, 3-SECOND DELAY
            portb=0x21;            //RB0 ON, RB5 ON, MAIN RED, SDRY GREEN
            delay_s(15);    //LOOP 1 SECOND DELAY 15 TIMES, 15-SECOND DELAY
            portb=0x11;            //RB0 ON, RB4 ON, MAIN RED, SDRY YELLOW
            delay_s(4);    //LOOP 1 SECOND DELAY 4 TIMES, 4-SECOND DELAY
        }
    }    
}
It compiles to 112 words of ROM and 2 bytes of RAM which is somewhat less that your assembler version.
Rich (BB code):
Memory Usage Report
===================
RAM available:224 bytes, used:2 bytes (0.9%), free:222 bytes (99.1%), 
Heap size:222 bytes, Heap max single alloc:95 bytes
ROM available:2048 words, used:112 words (5.5%), free:1936 words (94.5%)
 
Last edited:

AlexR

Joined Jan 16, 2008
732
I just realised that I missed out a couple of delay instructions.
With the the code corrected it compiles to 118 bytes of ROM and 2 bytes of RAM, still smaller than your assembler code and way way smaller the code produced by HiTechC lite.
Rich (BB code):
//
//    6-LIGHT, 4-WAY INTERSECTION TRAFFIC CONTROL SIGNAL
//    RYAN GOFF
//    JAN-14-2011
//    PIC16F628A
//    HIGH-TECH C COMPILER, MPLAB IDE
//
//    THIS PROGRAM IS FOR A 6-LIGHT INTERSECTION TRAFFIC CONTROL
//    SIGNAL WHERE BOTH THE MAIN TRAFFIC LANES (MAIN) AND SECONDARY
//    TRAFFIC LANES (SDRY) HAVE A SINGLE SET OF RED, YELLOW, GREEN
//    LIGHTS WHICH WILL CYCLE TO SAFELY CONTROL TRAFFIC WHILE
//    OPERATED IN THE NORMAL CYCLE.  THE SIGNAL ALSO HAS 2 NIGHT-
//    MODE CYCLES WHERE MAIN TRAFFIC LANES RECEIVE A FLASHING YELLOW
//    SIGNAL WHILE SECONDARY TRAFFIC LANES RECEIVE A FLASHING RED
//    SIGNAL, OR ALL TRAFFIC LANES RECEIVE A FLASHING RED SIGNAL.
//    SELECTION OF EITHER OF THESE NIGHT-MODE CYCLES IS DEPENDENT ON
//    THE POSITION OF A SINGLE ON-OFF-ON SWITCH WHICH WILL INPUT
//    HIGH TO porta.0 OR porta.1.  WHEN BOTH INPUTS ARE LOW, NORMAL CYCLE
//    OPERATION RESULTS.  THE SIGNAL IS PROGRAMMED TO NEVER ALLOW AN
//    UNSAFE SIGNAL CONDITION, THEREFORE, TRANSITION FROM NORMAL
//    OPERATION TO A NIGHT-MODE CYCLE OR VISE-VERSA IS NOT
//    INSTANTANEOUS, AND WILL OCCUR ONLY AT THE PROGRAMMED SAFE
//    POINT.
//
/****************************************************************/

#include <system.h>
#pragma CLOCK_FREQ 48000
#pragma DATA _CONFIG, _CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT
//    INTERNAL 48KHz CLOCK, PWRT, NO PROTECTION


/***************************************************************/

void main()
{
    pcon.OSCF = 0;                // LOW POWER 48KHZ INTOSC
    cmcon = 0x07;                // COMPARATORS OFF
    trisa = 0x03;                // porta.0 AND porta.1 INPUT, OTHERS OUTPUT
    trisb = 0;                    // ALL PORT B ARE OUTPUTS              //ALL PORT B ARE OUTPUTS

    while(1)
    {
        while (porta .0 == 1)    // WHILE INPUT AT porta.0, NMRR
        {
            portb = 0x08;        // RB3 ON, SECONDARY RED, ALL OTHERS OFF
            delay_ms(250);
            delay_ms(250);
            portb = 0x01;
            delay_ms(250);
            delay_ms(250);        // RB0 ON, MAIN RED, ALL OTHERS OFF

        }
        while (porta .1 == 1)    // WHILE INPUT AT porta.1, NMRY
        {
            portb = 0x08;
            delay_ms(250);
            delay_ms(250);        // RB3 ON, SECONDARY RED, ALL OTHERS OFF
            portb = 0x02;        // RB1 ON, MAIN YELLOW, ALL OTHERS OFF
            delay_ms(250);
            delay_ms(250);
        }
        if ((porta .0 != 1)&&(porta .1 != 1))    // porta.0 AND porta.1 NO INPUT
        {
            portb = 0x09;        // RB0 ON, RB3 ON, MAIN RED, SDRY RED
            delay_s(3);            // 3-SECOND DELAY
            portb = 0x0C;        // RB2 ON, RB3 ON, MAIN GREEN, SDRY RED
            delay_s(20);        // 20-SECOND DELAY
            portb = 0x0A;        // RB1 ON, RB3 ON, MAIN YELLOW, SDRY RED
            delay_s(4);            // 4-SECOND DELAY
            portb = 0x09;        // RB0 ON, RB3 ON, MAIN RED, SDRY RED
            delay_s(3);            // 3 TIMES, 3-SECOND DELAY
            portb = 0x21;        // RB0 ON, RB5 ON, MAIN RED, SDRY GREEN
            delay_s(15);        // 15 TIMES, 15-SECOND DELAY
            portb = 0x11;        // RB0 ON, RB4 ON, MAIN RED, SDRY YELLOW
            delay_s(4);            // 4 TIMES, 4-SECOND DELAY
        }
    }
}
Rich (BB code):
Memory Usage Report
===================
RAM available:224 bytes, used:2 bytes (0.9%), free:222 bytes (99.1%), 
Heap size:222 bytes, Heap max single alloc:95 bytes
ROM available:2048 words, used:118 words (5.8%), free:1930 words (94.2%)
 

MMcLaren

Joined Feb 14, 2010
861
Hi Ryan (ke5nnt),

When I tried the "new" free version of Hi-Tech that comes with MPLAB a couple of years ago I was utterly shocked when I saw the code it generated. They tell you it's not optimized but, gadz, it almost seemed that they went out of there way to generate garbage code. If the "free" Hi-Tech version is meant to be an advertisement or enticement to purchase their over-priced full versions, I think it back-fired. I won't go near Hi-Tech with a ten foot pole and I'm perfectly happy running the free/lite version of Boostc in my MPLAB environment.

Good luck... Regards, Mike
 

cheezewizz

Joined Apr 16, 2009
82
Yep I tend to agree with MMcLaren here where it seems that rather than simply not optimising the compiled code HiTechC bulks it up a bit to make the paid for version more attractive. I abandoned ship for AVRs after a while just because avr-gcc is awesome and free. Mind you I do appreciate that a PIC with more memory isn't usually that much of a step up cost wise, certainly far cheaper for the hobbyist to take that route than spend hundreds on the compiler.
 

t06afre

Joined May 11, 2009
5,934
If I understand the C right, there's some good bloat in T06AFREs example too.
I think this:
Rich (BB code):
42:                        LCD_DATA = ((c >> 4) | (c << 4)& 0xF0);
   7B6    0872     MOVF 0x72, W
   7B7    00F0     MOVWF 0x70
   7B8    0E70     SWAPF 0x70, W
   7B9    39F0     ANDLW 0xf0
   7BA    00F0     MOVWF 0x70
   7BB    39F0     ANDLW 0xf0
   7BC    00F1     MOVWF 0x71
   7BD    0E72     SWAPF 0x72, W
   7BE    390F     ANDLW 0xf
   7BF    0471     IORWF 0x71, W
   7C0    0086     MOVWF 0x6
could be shortened to:
Rich (BB code):
42:                        LCD_DATA = ((c >> 4) | (c << 4)& 0xF0);
SWAPF 0x72, W
ANDLW 0xf0
MOVWF 0x6
A 72% reduction in code.
This is quite interesting. I noticed the bloating my self. In fact I was not happy with the result. But I had some cold beers calling my name. And a movie on the TV was about to start.
Giving the problem some thinking I came up with some ways to rewrite my program here is some examples. First in PRO mode. Full optimation. I am using HI-Tech C
This is OK I guess.
Rich (BB code):
42:                       c = (c >> 4) | (c << 4);
   7BC    0EF1     SWAPF 0x71, F
43:                        c = c&0xF0;
   7B9    30F0     MOVLW 0xf0
   7BD    05F1     ANDWF 0x71, F
44:                         LCD_DATA = c;
   7BE    0871     MOVF 0x71, W
   7BF    0086     MOVWF 0x6
And Also this. It is in fact better nice and compact
Rich (BB code):
46:                      LCD_DATA = ( ( c >> 4 ) & 0x0F );
   7BD    0E71     SWAPF 0x71, W
   7BE    390F     ANDLW 0xf
   7BF    0086     MOVWF 0x6
Now let us try lite mode
:eek:
Oh my Ouch......

Rich (BB code):
 42:                       c = (c >> 4) | (c << 4);
   79B    0873     MOVF 0x73, W
   79C    00F0     MOVWF 0x70
   79D    3004     MOVLW 0x4
   79E    1003     BCF 0x3, 0
   79F    0DF0     RLF 0x70, F
   7A0    3EFF     ADDLW 0xff
   7A1    1D03     BTFSS 0x3, 0x2
   7A2    2F9E     GOTO 0x79e
   7A3    0873     MOVF 0x73, W
   7A4    00F1     MOVWF 0x71
   7A5    3004     MOVLW 0x4
   7A6    1003     BCF 0x3, 0
   7A7    0CF1     RRF 0x71, F
   7A8    3EFF     ADDLW 0xff
   7A9    1D03     BTFSS 0x3, 0x2
   7AA    2FA6     GOTO 0x7a6
   7AB    0871     MOVF 0x71, W
   7AC    0470     IORWF 0x70, W
   7AD    00F2     MOVWF 0x72
   7AE    0872     MOVF 0x72, W
   7AF    00F3     MOVWF 0x73
43:                        c = c&0xF0;
   7B0    0873     MOVF 0x73, W
   7B1    39F0     ANDLW 0xf0
   7B2    00F0     MOVWF 0x70
   7B3    0870     MOVF 0x70, W
   7B4    00F3     MOVWF 0x73
44:                         LCD_DATA = c;
   7B5    0873     MOVF 0x73, W
   7B6    0086     MOVWF 0x6
Somewhat more bloated, but well it is lite mode and free
Rich (BB code):
46:                      LCD_DATA = ( ( c >> 4 ) & 0x0F );
   7AC    0871     MOVF 0x71, W
   7AD    00F0     MOVWF 0x70
   7AE    3004     MOVLW 0x4
   7AF    1003     BCF 0x3, 0
   7B0    0CF0     RRF 0x70, F
   7B1    3EFF     ADDLW 0xff
   7B2    1D03     BTFSS 0x3, 0x2
   7B3    2FAF     GOTO 0x7af
   7B4    0870     MOVF 0x70, W
   7B5    390F     ANDLW 0xf
   7B6    0086     MOVWF 0x6
Still much the same but also more bloated as expected
Rich (BB code):
45:                       LCD_DATA = (c >> 4) | (c << 4)& 0xF0;
   7A1    0873     MOVF 0x73, W
   7A2    00F0     MOVWF 0x70
   7A3    3004     MOVLW 0x4
   7A4    1003     BCF 0x3, 0
   7A5    0DF0     RLF 0x70, F
   7A6    3EFF     ADDLW 0xff
   7A7    1D03     BTFSS 0x3, 0x2
   7A8    2FA4     GOTO 0x7a4
   7A9    30F0     MOVLW 0xf0
   7AA    0570     ANDWF 0x70, W
   7AB    00F1     MOVWF 0x71
   7AC    0873     MOVF 0x73, W
   7AD    00F2     MOVWF 0x72
   7AE    3004     MOVLW 0x4
   7AF    1003     BCF 0x3, 0
   7B0    0CF2     RRF 0x72, F
   7B1    3EFF     ADDLW 0xff
   7B2    1D03     BTFSS 0x3, 0x2
   7B3    2FAF     GOTO 0x7af
   7B4    0872     MOVF 0x72, W
   7B5    0471     IORWF 0x71, W
   7B6    0086     MOVWF 0x6
For me this was a lesson learned I was under impression that it was much better to write c = (c >> 4) | (c << 4); then wanting to do the swapf instruction. But it turns out that ( c >> 4 ) produce much better code in most cases. I think LCD_DATA = (c >> 4) | (c << 4)& 0xF0; get bloated in pro mode due to Integral Promotion in C
 
Last edited:

thatoneguy

Joined Feb 19, 2009
6,359
Hi Ryan (ke5nnt),

When I tried the "new" free version of Hi-Tech that comes with MPLAB a couple of years ago I was utterly shocked when I saw the code it generated. They tell you it's not optimized but, gadz, it almost seemed that they went out of there way to generate garbage code. If the "free" Hi-Tech version is meant to be an advertisement or enticement to purchase their over-priced full versions, I think it back-fired. I won't go near Hi-Tech with a ten foot pole and I'm perfectly happy running the free/lite version of Boostc in my MPLAB environment.

Good luck... Regards, Mike
This is one of the biggest reasons I recommend BoostC for anybody just starting. Great code, and even if you buy the "full version", it's still nowhere near what some charge for their compilers. MikroC is good, we need to see a port from it here for the full comparison.

It really does look like Hi-Tech intentionally bloats code rather than simply not optimizing, that's sad.
 

AlexR

Joined Jan 16, 2008
732
As much as I dislike HiTechC I do think it's a bit unfair to accuse them of deliberately bloating their code. What you are seeing is simply the effects of non-optimised code.

When I the code that I ported to SourceBoostC is compiled with all optimisation turned off it compiles down to 199 bytes of ROM and 7 bytes of RAM. Ryan's HTC Lite code compiled to 292 bytes of ROM and 5 bytes RAM but in porting his code to SourceBoost I did get rid of 6 "for()" loops so in all probability there's not all that much difference between the un-optimised performance of the 2 compilers.

It does however show the importance of having good code optimisation built into the compiler and just how bad the so-called free compilers with crippled code optimisation can be.
 

thatoneguy

Joined Feb 19, 2009
6,359
As much as I dislike HiTechC I do think it's a bit unfair to accuse them of deliberately bloating their code. What you are seeing is simply the effects of non-optimised code.

When I the code that I ported to SourceBoostC is compiled with all optimisation turned off it compiles down to 199 bytes of ROM and 7 bytes of RAM. Ryan's HTC Lite code compiled to 292 bytes of ROM and 5 bytes RAM but in porting his code to SourceBoost I did get rid of 6 "for()" loops so in all probability there's not all that much difference between the un-optimised performance of the 2 compilers.

It does however show the importance of having good code optimisation built into the compiler and just how bad the so-called free compilers with crippled code optimisation can be.
Except for the fact that CLRWDT was called continually, even though the #pragma in the file had WDT_OFF, which even a non-optimizing compiler should recognize.

That and BoostC supports optimizations in all versions, including free and lite
 

AlexR

Joined Jan 16, 2008
732
I wouldn't worry too much about the "CLRWDT" instruction, it only adds 6 words to the general code bloat. I agree it should not be there but then a lot of the code should not be there but is because there is no optimisation. As is the case in most conspiracy theories I think its a simple case of a stuff-up rather than a deliberate effort to bloat the code.
Mind you the fact that their give-away code is so crippled does put me off buying anything from them.
 
Top