Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Can anyone explain this C18 feature/bug?

Status
Not open for further replies.
Since this thread started, I've been looking at various compilers.... At the documentation... The why's and why not's.

I can see why the makers of C18 have done this and , as has been noted by programmers here, they have provided the document AND the override to use at your discretion.

The topic "Integer promotion" explains why they kept constant literals as 8 bit.

I agree with 3V0....(even though I have my own issues with C18 ).
 
The topic "Integer promotion" explains why they kept constant literals as 8 bit.

Can someone point me to this documentation or explain here why treating literal constants as 8 bit is even slightly sensible?

I fully understand why you would want this on variable calculations but can not see any advantage treating constants as 8 bit.

I've googled but can't find the why.

Having said that it is documented and there is a mechanism in place to make it use 16 bits. Not exactly a show stopper.
Using the -oi option just causes bloated code. As a programmer I'm aware of what size variable to use and don't want automatic promotion. I just want my expressions evaluated correctly and not have to pick up a calculator.

I have yet to find ANY other compiler that interprets the standard this way. Can anyone find one?

If C18s way of doing things is correct then on a 16 bit machine doing,
long a = 256*256
should result in a=0 as it should overflow an integer. Does anyone know of a compiler that does this?

Mike.
 
It's quite simple;

1. The compilers job is to carry out the instructions of the user.

2. The compiler allows 32bit variables, so it should correctly support 32bit variables and simple assignments.

3. A very simple constant was assigned to a 32bit variable, and the compiler FAILED miserably.

I hope for their sake they fix it soon.

And what's with the band-aid solution of being able to force it to use 16bits? It's a 32bit variable!
The user is assigning a 32bit constant to a 32bit variable, this is not rocket science. Why would a user possibly want to be resitricted to only being able to assign 8bit constants to 32bit variables? Even an absolute beginner would see what a monumental failure that is.
 
Pommie... I agree... The documentation (" hlpC18ug....Language specifics...ISO divergence") explains

For example:

unsigned char a, b;
unsigned i;
a = b = 0x80;
i = a + b; /* ISO requires that i == 0x100, but in C18 i == 0 */
Note that this divergence also applies to constant literals. The chosen type for constant literals is the first one
from the appropriate group that can represent the value of the constant without overflow.

For example:

#define A 0x10 /* A will be considered a char unless -Oi
specified */
#define B 0x10 /* B will be considered a char unless -Oi
specified */
#define C (A) * (B)
unsigned i;
i = C; /* ISO requires that i == 0x100, but in C18 i == 0 */

Even if they made constants 16 bits by default... you would still see a little bloating of the code

According to this... they have no intention of fixing it.
 
Just above the text Ian quoted it says

ISO mandates that all arithmetic be performed at int precision or greater. By default,
MPLAB C18 will perform arithmetic at the size of the largest operand, even if both
operands are smaller than an int. The ISO mandated behavior can be instated via the
-Oi command-line option.
I did not see the word 'bug'.

Even 100% ISO compliant compilers are not required to determine the result type of literal math.

Casting gives the desired result without bloating your code and should compile correctly with any C compiler.

If Microchip changes the default behavior at this late date there is a good chance it will break some customers code. If there is a change I would expect it to be in invoked by command line option.

We need to give Microchip some credit for offering not one but 2 18F compilers. There is a good chance that a manager or set of managers are fighting the bean counters who see the software development tools as cost that could be trimmed.
 
Casting gives the desired result without bloating your code and should compile correctly with any C compiler.
True and so why have the stupid behaviour in the first place. Just do it right.
If Microchip changes the default behavior at this late date there is a good chance it will break some customers code. If there is a change I would expect it to be in invoked by command line option.
How can it break code? The only people that know about this are the ones that have had a huge chunk bitten out of their arse and found a work around.
We need to give Microchip some credit for offering not one but 2 18F compilers. There is a good chance that a manager or set of managers are fighting the bean counters who see the software development tools as cost that could be trimmed.
Why give them credit? The one they wrote (C18) gets it wrong. The one they bought in (HiTech) gets it right. (I'm not going to mention how horrible the code produced by HiTech is, that is a whole new subject.)

Mike.
 
As a new hire I was gifted with the job of verifying compiler bugs, writing test cases etc. There is no way I can impress on you how even the most innocent change to a compiler can cause unforeseen problems.


Give Microchip the credit because they are providing compilers.
 
Mike is Boost C that much better ?

I really Like MikroC but you can't use it with Mplab and I really don't like the IDE for it and the librarys should be open. There amost auto included and that's a pain some times.
 
Last edited:
The 30 seconds it takes to be careful about your operations, add modifiers to literals and cast variables will be paid back 100X if you every have to re-host code across different bit size machines or architectures. The C18 default is not WRONG for it's target device, small memory 8 bit micro-controllers (many 8 bit expressions and 8 bit data flow on interfaces). C18 looks a lot like a "C compiler" but it's not unless you flip the ANSI switch, this is not necessarily a bad thing.

https://www.electro-tech-online.com/custompdfs/2012/03/en555854.pdf
 
Last edited:
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top