Searching \ for '[PIC] Bug in Microchip mcc18 std library?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Bug in Microchip mcc18 std library?'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Bug in Microchip mcc18 std library?'
2005\02\14@170646 by Hulatt, Jon

picon face
Hi All,

I've observed this evening that the implementation of putrsUSART in the
std libs is somewhat odd.

putrsUSART sends a string from rom to the USART.  it's defined as:-

void putrsUSART(const rom char *data);

It's my understanding that C, and C++ for that matter, represent strings
as null terminated arrays of char. And, logically, the string does not
include the null terminator. So, the implementation of putrsUSART should
not include the terminating null.

Here is the definition of the function:-

void putrsUSART(const rom char *data)
{
 do
 {  // Transmit a byte
   while(BusyUSART());
   putcUSART(*data);
 } while( *data++ );
}

The effect of this definition is that, for example, calling
putrsUSART("Hello"); outputs 6 chars - the 5 of Hello, and then a
terminating null.

It happens because the while loop control statement is a postfix
increment, rather than a prefix increment. This also leads to a side
effect of poor handling of null strings- IMO putrsUSART(""); should do
precisely nothing- in this implementation it will output a null.

So, if i'm right in thinking that this function should not include the
terminating null charactor in it's output, then this is a bug. Do you
agree with me? and is there a microchip bug reporting thing out there
anywhere?

IMHO a better implementation would be:-

void putrsUSART(const rom char *data)
{
 while( *data++ );
 {  // Transmit a byte
   while(BusyUSART());
   putcUSART(*data);
 }
}

ie. The condition is evaluated ahead of time.

Do you agree that this is a bug?

(Yes, I've already recompiled my std libraries, but I don't feel
comfortable with using non-standard, standard libs.)

Jon

2005\02\14@171409 by Robin Abbott

flavicon
face
A quick rat hole - does C18 not allow any pointer to freely point to ROM
and RAM ? Would explain some strange constructs in the C18 program that
I have been converting !

Robin Abbott

Forest Electronic Developments

01590 681511
+44 1590 681511 (phone/fax)

See our web pages : http://www.fored.co.uk



{Original Message removed}

2005\02\14@174959 by olin_piclist

face picon face
Hulatt, Jon wrote:
> void putrsUSART(const rom char *data)
> {
>   do
>   {  // Transmit a byte
>     while(BusyUSART());
>     putcUSART(*data);
>   } while( *data++ );
> }

This is a bug if for no other reason than it always emits at least one byte.
I also don't like the busy wait.

<soapbox>Stuff like *DATA++ reminds me of why C is so evil in the first
place.  It's bad enough that the language allows you to put three separate
things into one statement, but even worse when someone writes code like
that.  No optimizations would have been lost by writing this as two lines:

 data++;           //advance to next character in string
 } while (*data);  //back to handle next character

C has encouraged a whole generation of programmers to write cutesy obtuse
code.</soapbox>


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\14@191030 by piclist

flavicon
face
On Mon, 14 Feb 2005, Robin Abbott wrote:

> does C18 not allow any pointer to freely point to ROM and RAM ?

It does not.

--
John W. Temples, III

2005\02\14@191651 by Lee Jones

flavicon
face
{Quote hidden}

By convention, a pointer to a string is aimed at the first char
in the array.  Using a pre-increment would ignore the first char.

> This also leads to a side effect of poor handling of null strings-
> IMO putrsUSART(""); should do precisely nothing

Agreed.

> So, if i'm right in thinking that this function should not include
> the terminating null charactor in it's output, then this is a bug.
> Do you agree with me?

Yes.

{Quote hidden}

I've never used MCC18, but I have used C for decades.  Possibly
MCC18 has a non-ANSI implementation of use of semi-colons after
loop constructs, such as while.  My following analysis assumes
that the rules of ANSI C hold true.

The while() construct executes a single statement while the
condition is true.  The statement can either be a simple statement
or a compound statement.

Your inclusion of a semi-colon at the end of the first while()
causes that while to loop until the terminating null has been
reached.  It leaves the pointer aimed at the first char after
that null.  The compound statement following it will wait for the
USART to be non-busy then emit a single char -- the char following
the first string's terminating null.

I think it should be written as follows:

void putrsUSART(const rom char *data)
{
   while( *data )                        /* repeat until terminating null */
   {
       while( BusyUSART() )                /* spin wait (BAD IDEA) until ready */
           ;
       putcUSART(*data);                /* load one char into USART */
   }
   return;
} /* putrsUSART() */

Note the simple statement of the second while() loop is set off
on a seperate line so that it is obvious.  Just because C allows
poor human engineering doesn't mean you can't use indentation and
white space to make your design clearer & more obvious.

And, yes, I know I don't _need_ the return; statement but I like
to be obvious when I revisit the routine (months or years later).

The use of a spin wait in a routine that may wait for more than
30 milliseconds (i.e. 1 char time at 300 baud) is not a good idea
if the PIC has any other tasks to complete.

                                               Lee Jones


2005\02\14@191744 by Andrew Warren

flavicon
face
Olin Lathrop <spam_OUTpiclistTakeThisOuTspammit.edu> wrote:

> > } while( *data++ );
> ....
> Stuff like *DATA++ reminds me of why C is so evil in the first
> place.  It's bad enough that the language allows you to put three
> separate things into one statement, but even worse when someone
> writes code like that.  No optimizations would have been lost by
> writing this as two lines:
>
> data++;           //advance to next character in string
> } while (*data);  //back to handle next character

Olin:

As you become more familiar with C, idioms such as "while(*p++)" will
eventually seem no more complicated to you than "decfsz count", which
also puts at least three things into one statement...  

There's lots of bad C code in the world, but that one line isn't an
example of it.

-Andy

P.S. By the way, your code isn't equivalent to the original.

=== Andrew Warren -- .....aiwKILLspamspam@spam@cypress.com
=== Principal Design Engineer
=== Cypress Semiconductor Corporation
=== (but open to offers)
===
=== Opinions expressed above do not
=== necessarily represent those of
=== Cypress Semiconductor Corporation

2005\02\14@191934 by Lee Jones

flavicon
face
>From lee Mon Feb 14 16:23:35 2005
To: piclistspamKILLspammit.edu
Subject: Re:  [PIC] Bug in Microchip mcc18 std library?
Status: R

Oops, as soon as I sent my last message I realized I had
forgotten to add a crucial line to the revised funciton.


{Quote hidden}

By convention, a pointer to a string is aimed at the first char
in the array.  Using a pre-increment would ignore the first char.

> This also leads to a side effect of poor handling of null strings-
> IMO putrsUSART(""); should do precisely nothing

Agreed.

> So, if i'm right in thinking that this function should not include
> the terminating null charactor in it's output, then this is a bug.
> Do you agree with me?

Yes.

{Quote hidden}

I've never used MCC18, but I have used C for decades.  Possibly
MCC18 has a non-ANSI implementation of use of semi-colons after
loop constructs, such as while.  My following analysis assumes
that the rules of ANSI C hold true.

The while() construct executes a single statement while the
condition is true.  The statement can either be a simple statement
or a compound statement.

Your inclusion of a semi-colon at the end of the first while()
causes that while to loop until the terminating null has been
reached.  It leaves the pointer aimed at the first char after
that null.  The compound statement following it will wait for the
USART to be non-busy then emit a single char -- the char following
the first string's terminating null.

I think it should be written as follows:

void putrsUSART(const rom char *data)
{
   while( *data )                        /* repeat until terminating null */
   {
       while( BusyUSART() )                /* spin wait (BAD IDEA) until ready */
           ;
       putcUSART(*data);                /* load one char into USART */
       data++;                                /* move on to next char */
   }
   return;
} /* putrsUSART() */

Note the simple statement of the second while() loop is set off
on a seperate line so that it is obvious.  Just because C allows
poor human engineering doesn't mean you can't use indentation and
white space to make your design clearer & more obvious.

And, yes, I know I don't _need_ the return; statement but I like
to be obvious when I revisit the routine (months or years later).

The use of a spin wait in a routine that may wait for more than
30 milliseconds (i.e. 1 char time at 300 baud) is not a good idea
if the PIC has any other tasks to complete.

                                               Lee Jones



2005\02\14@192013 by piclist

flavicon
face
On Mon, 14 Feb 2005, Hulatt, Jon wrote:

> So, the implementation of putrsUSART should
> not include the terminating null.

> Do you agree that this is a bug?

A misfeature, perhaps, but not a bug.  The manual documents the
behavior you describe.

--
John W. Temples, III

2005\02\14@194105 by piclist

flavicon
face
On Mon, 14 Feb 2005, Olin Lathrop wrote:

> This is a bug if for no other reason than it always emits at least one byte.

Not if that's what it's documented to do.

> <soapbox>Stuff like *DATA++ reminds me of why C is so evil in the first
> place.  It's bad enough that the language allows you to put three separate
> things into one statement, but even worse when someone writes code like
> that.  No optimizations would have been lost by writing this as two lines:
>
>  data++;           //advance to next character in string
>  } while (*data);  //back to handle next character

*ptr++ is a very common C construct.  I would imagine most experienced
C programmers would find your version less readable, not more.

--
John W. Temples, III

2005\02\14@201409 by John J. McDonough

flavicon
face
----- Original Message -----
From: <.....piclistKILLspamspam.....xargs.com>
Subject: Re: [PIC] Bug in Microchip mcc18 std library?


> *ptr++ is a very common C construct.  I would imagine most experienced
> C programmers would find your version less readable, not more.

common is an understatement.  OK, maybe 90% of the time it seems like it is
the ubiquitous 'p', so while *ptr++ might not be that common, *p++ is
everywhere!

Telling a C programmer to write
  data++;
 } while (*data);

Is like telling a BASIC or FORTRAN programmer that I=I+1 is too confusing
and somehow the code would be more clear if he wrote
   K=I
   I=K+1
yeah, right.

--McD


2005\02\14@213103 by Bob Ammerman

picon face
> I think it should be written as follows:
>
> void putrsUSART(const rom char *data)
> {
>    while( *data ) /* repeat until terminating null */
>    {
> while( BusyUSART() ) /* spin wait (BAD IDEA) until ready */
>     ;
> putcUSART(*data); /* load one char into USART */
>    }
>    return;
> } /* putrsUSART() */
>

Unfortunately, this is still broken. How about:


void putrsUSART(const rom char *data)
{
   while( *data ) /* repeat until terminating null */
   {
       while( BusyUSART() )
            /*spin wait for UART*/ ;
      putcUSART(*data); /* load one char into USART */
      +data;
   }
   return;
} /* putrsUSART() */

Bob Ammerman
RAm Systems


2005\02\15@032132 by ThePicMan

flavicon
face

Olin Lathrop wrote:

><soapbox>Stuff like *DATA++ reminds me of why C is so evil in the first
>place.  It's bad enough that the language allows you to put three separate
>things into one statement, but even worse when someone writes code like
>that.  No optimizations would have been lost by writing this as two lines:
>
>  data++;           //advance to next character in string
>  } while (*data);  //back to handle next character
>
>C has encouraged a whole generation of programmers to write cutesy obtuse
>code.</soapbox>

Great power requires great responsability..
C was made for Real Programmers (tm), others have options like BASIC. *grin*

2005\02\15@032357 by Wouter van Ooijen

face picon face
> C has encouraged a whole generation of programmers to write
> cutesy obtuse code.

Nobody denies that! But at least they write somewhat *portable* cutesy
obtuse (that's beyond my knowledge of english, but I can guess) code. C
is often reffered to as 'the best assembler around', so you of all
people should love it ;) (and the object code generated by a C compiler
is in relocateable format!)

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\15@032357 by Wouter van Ooijen

face picon face
> I've observed this evening that the implementation of
> putrsUSART in the std libs is somewhat odd.

I mostly avoid using the uChip libraries. I never got the LCD lib to
work, so I wrote my own. There was some trouble with the UART lib too,
so again I wrote my own (it is not that hard to do).

So don't feel guilty about changing the lib, although you should now
regard it as 'your' lib, not a standard lib.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\15@032357 by Wouter van Ooijen

face picon face
> A quick rat hole - does C18 not allow any pointer to freely
> point to ROM
> and RAM ? Would explain some strange constructs in the C18
> program that
> I have been converting !

AFAIK is does not.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\15@035219 by Hulatt, Jon

picon face
lol.


>Your inclusion of a semi-colon at the end of the first while() causes
that while to loop until the terminating null has been >reached.  It
leaves the pointer aimed at the first char after that null.  The
compound statement following it will wait for >the USART to be non-busy
then emit a single char -- the char following the first string's
terminating null.

My inclusion of a semi-colon was a typo ;-)

However, even without it, my code doesn't work right.

while( *data++ )
{  
  // Transmit a byte
  while(BusyUSART());
  putcUSART(*data);
}

What the Microchip compiler is doing for that is basically while
(*(data++)) , so the first char is always missed. My bad. Or is it? I'm
going to check the text books today to see what the ANSI operator
precedence should be. I thought that would work.

Jon

{Original Message removed}

2005\02\15@035530 by Hulatt, Jon

picon face


>The use of a spin wait in a routine that may wait for more than 30
milliseconds (i.e. 1 char time at 300 baud) is not a good >idea if the
PIC has any other tasks to complete.

makes me very very glad Microchip include the library source code and a
way of recompiling. At least we can see that that is what it does.





2005\02\15@043542 by Ake Hedman

flavicon
face
John J. McDonough wrote:

{Quote hidden}

Who really cares... An experienced programmer will have no problem with either form. The
...
} while (*p++);
form will probably be the most common  but I can't see why anyone of them should be easier  to read.

Cheers
/Ake

--  ---
Ake Hedman (YAP - Yet Another Programmer)
eurosource, Brattbergavägen 17, 820 50 LOS, Sweden
Phone: (46) 657 413430 Cellular: (46) 73 84 84 102
Company home: http://www.eurosource.se      Kryddor/Te/Kaffe: http://www.brattberg.com
Personal homepage: http://www.eurosource.se/akhe
Automated home: http://www.vscp.org

2005\02\15@044236 by Hulatt, Jon

picon face
That's pretty much what i've now decided to do.

I did previously get the LCD lib working (with an lcd you supplied me,
no less!), but to have to recompile the libraries to match the pin/port
configuration you're using seems a bit c**p to me.



{Original Message removed}

2005\02\15@052230 by Jan-Erik Soderholm

face picon face
Hulatt, Jon wrote :

> I did previously get the LCD lib working, but to have to
> recompile the libraries to match  the pin/port
> configuration you're using seems a bit c**p to me.

Right, that's the major problem with obj libraries.
And also why many uses source code "libraies" (usualy as
include files) so you can use compile/assembly time calculations
and conditional builds on the fly. Changing pins for the LCD
whould in that case need no changes to the include file (if
written properly) just setting up some symbols i the main code.

A "LCD library" with *fixed* pin assignments seems pretty
useless to me.

And I'd guess that it doesn't matter realy if the source was
in C or ASM...

Jan-Erik.



2005\02\15@074947 by Bob Ammerman

picon face

----- Original Message -----
From: "Wouter van Ooijen" <wouterspamspam_OUTvoti.nl>
To: "'Microcontroller discussion list - Public.'" <@spam@piclistKILLspamspammit.edu>
Sent: Tuesday, February 15, 2005 3:23 AM
Subject: RE: [PIC] Bug in Microchip mcc18 std library?


>> A quick rat hole - does C18 not allow any pointer to freely
>> point to ROM
>> and RAM ? Would explain some strange constructs in the C18
>> program that
>> I have been converting !
>
> AFAIK is does not.
>
> Wouter van Ooijen

It does not, and for a very good reason. Since ROM and RAM are completely
separate address spaces, that don't even have the same pointer width (RAM =
12 bits, ROM = 16 or 22? bits), there would be quite a bit of overhead to
create 'universal' pointers. I suppose it could be done using a 24-bit
format where the upper bit indicated which memory type to access, but I just
think that would be ugly (and slow).

Bob  Ammerman
RAm Systems


2005\02\15@080625 by Per Linne

flavicon
face
Is there a reason you can't use:

void putrsUSART(const rom char *data)
{
 do
  {  // Transmit a byte
    while(BusyUSART());
    putcUSART(*data);
  } while( *++data );      // <<<<<<<<
}

?

PerL


{Quote hidden}

2005\02\15@082020 by Michael Rigby-Jones

picon face


{Quote hidden}

But speed may be an acceptable trade off sometimes for the convienience
of a function that can accept a pointer to either data or program
memory.  HiTechs compiler can do this, but with a small limitation.  If
the pointer value is below the maximum data memory address, it is deemed
to be pointing to data memory, otherwise it's pointing to program
memory.  Of course this does introduce some overhead and is problematic
if you want to access low program memory with the same pointer.
However, the linker will always place constant data above this address,
so for the majority applications this solution works very well.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\02\15@082332 by Michael Rigby-Jones

picon face


{Quote hidden}

Consider what would happen if the pointer were pointing to a NULL
string.  The NULL would be sent, and then the next character (some
random memory address) would be checked.  This is a very dangerous
function, it could potentially send out huge amounts of garbage data.

IMO the value should always be checked BEFORE sending it, not after.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\02\15@084035 by Bob Ammerman

picon face

----- Original Message -----
From: "Per Linne" <RemoveMEper.linnespamTakeThisOuTswipnet.se>
To: "Microcontroller discussion list - Public." <piclistEraseMEspam.....mit.edu>
Sent: Tuesday, February 15, 2005 8:06 AM
Subject: Re: [PIC] Bug in Microchip mcc18 std library?


{Quote hidden}

This breaks (badly) in the case of a null string.

Bob Ammerman
RAm Systems


2005\02\15@084739 by John J. McDonough

flavicon
face
----- Original Message -----
From: "Ake Hedman" <EraseMEakhespameurosource.se>
Subject: Re: [PIC] Bug in Microchip mcc18 std library?


> Who really cares... An experienced programmer will have no problem with
> either form. The
>
> ...
>  } while (*p++);
>
> form will probably be the most common  but I can't see why anyone of
> them should be easier  to read.

While the experienced programmer will be able to read either, the amount of
time it takes is substantially different. When I see the above form, I know
I'm scanning until the end of the string without even thinking about it.

But if I see

   data++;
   } while (*data);

about a million questions come to mind.  Whey did the programmer chooses to
do this so strangely?  Was there supposed to be something after the pointer
is incremented that I missed?  Is my source corrupt?  Is it just that this
guy is really uncomfortable with the language?  If he is, then every other
line is suspect.  Maybe he's a displaced Ada programmer and I should be
looking for Ada idioms insted of C idioms.

Different is rarely better.  In some cases, like user interface, even if
it's better it's not better!  C may have been the first language where
standardization helped a lot.  C is chock full of idioms that allow a very
simple, terse language to be highly effective.  Sure, there are a hundred
ways to do anything, but doing something differently, just for the sake of
being different takes longer for the original programmer, longer for someone
reading it, and makes it more likely that a bug will be missed.

Also, somewhere along this thread, a poster suggested that the optimizations
are the same.  That is absolutely not true.  There is no language for which
optimization has been researched so thoroughly as C.  However, many of the
optimizations rely on recognizing the common idioms.  When the programmer
obfuscates his intent with strained constructs, he makes it less likely that
the compiler will recognize what he is doing.

Now, truth be told, I don't know about C18, and I would hope that is doesn't
go nuts with optimizations.  In an embedded environment, I want to have a
clear picture of what is running in that silicon.  But in many C compilers
these days, the amount of optimization is breathtaking, and attempts to make
the code more efficient will often make it less, by obscuring the
programmer's intent from the compiler.

--McD


2005\02\15@090230 by Hulatt, Jon

picon face

{Quote hidden}

I really wouldn't like the idea of not distinguishing the difference
between the two types of pointer. They *are* different, and IMHO a
compiler "hack" to make them compatible is a recipe for disaster.

For a start, rom pointers are *always* const, ram pointers need not be.
And think of the utter mess of trying to deal with pointers-to-pointers,
ie. void **. Eugh.

2005\02\15@090331 by Sergio Masci

flavicon
face

----- Original Message -----
From: Bob Ammerman <RemoveMErammermanEraseMEspamEraseMEverizon.net>
To: Microcontroller discussion list - Public. <RemoveMEpiclistspam_OUTspamKILLspammit.edu>
Sent: Tuesday, February 15, 2005 12:48 PM
Subject: Re: [PIC] Bug in Microchip mcc18 std library?


{Quote hidden}

This is one reason why I added function overloading to XCSB. It is an eligant
solution to the problem of using pointers with different address spaces i.e.
have two (or more) functions that generate code specifically for a pointer of a
given address space.

e.g.
       strcmp(char *str1, char *str2)
and
       strcmp(char *str1, char * const str2)

Previously it was necessary to provide specialised functions to handle pointers
to code space. So "strcmp" have a code space counterpart called "strcmp_code"
but users were free to use an incorrect address space pointer with either
function (RAM space where code space was required). This caused inexperienced
users many problems. Now the compiler not only validates correct pointer use
with parameters, but it also removes the burden from the user by selecting the
correct function based on the parameters supplied.

Another nice thing about function overloading is that it allows further
optimisation of generated code. Consider the C function:

       int SUM(int a, int b)

Any parameters you pass to it must be promoted to "int" before the function is
called. However if you have alternative versions such as:

       int SUM(byte a, byte b)
       int SUM(int a, byte b)
       int SUM(byte a, int b)

Then the compiler is better able to optimise the generated code based on the
parameters supplied to the function. i.e. it fits the function (and the
generated code) to the suplied parameters rather than doing extra work on the
parameters to make them fit the function. Of course this doesn't stop you using
functions as you did before, you are not forced to create functions for every
possible combination of parameters. You just have a lot more control over what
is generated.

Using the "inline" function call stratergy with some overloaded functions and
not others allows you to eliminate function call overheads in cases where the
generated code is less than the code required to call the function while keeping
a single function where the generated code is large.

e.g.
       proc inline byte SUM(byte a, byte b)
               return a + b
       endproc

       proc int SUM(int a, int b)
               return a + b
       endproc

       byte    x, y, z

       x = SUM(y, z)

would generate

       movf    y,w
       movwf    x
       movf    z,w
       addwf    x

whereas

       int    x, y, z

       x = SUM(y, z)

would generate

       movf    y+0,w
       movwf    a_SUM_arg+0
       movf    y+1,w
       movwf    a_SUM_arg+1
       movf    z+0,w
       movwf    b_SUM_arg+0
       movf    z+1,w
       movwf    b_SUM_arg+1
       call    SUM
       movf    result_SUM+0,w
       movwf    x+0
       movf    result_SUM+1,w
       movwf    x+1


Regards
Sergio Masci

http://www.xcprod.com/titan/XCSB - optimising PIC compiler
FREE for personal non-commercial use



2005\02\15@091712 by Alan B. Pearce

face picon face
>> Is there a reason you can't use:
>>
>> void putrsUSART(const rom char *data)
>> {
>>  do
>>   {  // Transmit a byte
>>     while(BusyUSART());
>>     putcUSART(*data);
>>   } while( *++data );      // <<<<<<<<
>> }
>>
>> ?
>>
>> PerL
>
>This breaks (badly) in the case of a null string.

For that reason I would have thought the way to do it would be

   while( *data )
      {while(BusyUSART());
       putcUSART(*data++)};

But then I am not experienced with C, so this may still have errors.
   

2005\02\15@093830 by Ake Hedman

flavicon
face
John.

also for me the construct

  data++;
} while (*data);


looks a bit odd  but I have seen o many ways to program from different programmers that I don't bother anymore. Just this construct is not so hard to understand. The other form may however be hard for someone that is new to C but certainly not for someone that is fluid in C.

If the program have comments on things that are not obvious and the code is indented with some form of method (don't care which) its OK. Most professional programmers go through code from other programmers that use a different coding style then they or the group they work in use and as handwriting are different so is coding styles.
It may be just me but there are so many bugs to haunt down and so many things left to do that this isn't worth putting any time on. Anyway thousands of  man hours are spent on this on all companies .IMHO a total waste of time!

Best to add that this  is  just my view of the matter and anyone else have the right to put X% of there time on coding/debugging and X% on formating issues ( replace x and y with the numbers of preference).

And also this is not an attack on you John just general speaking. ;-)

Regards
/Ake

John J. McDonough wrote:

>{Original Message removed}

2005\02\15@094703 by olin_piclist

face picon face
Wouter van Ooijen wrote:
>> C has encouraged a whole generation of programmers to write
>> cutesy obtuse code.
>
> Nobody denies that! But at least they write somewhat *portable* cutesy
> obtuse (that's beyond my knowledge of english, but I can guess) code. C
> is often reffered to as 'the best assembler around', so you of all
> people should love it ;) (and the object code generated by a C compiler
> is in relocateable format!)

You seem to be thinking I was talking about C versus assembler, when I was
really just commenting about C as a language by itself.

It's interesting that the responses I've gotten are mostly along the lines
of "experienced C programmers are used to that".  I'm sure that's true, but
it seems this experience has numbed people to the awful problems inherent in
the system.

It's kindof like you live next to a polluted river.  After a while you don't
notice the smell anymore, and you get used to not swimming in the river or
growing your vegetables by the river bank.  Life goes on and seems normal,
and nobody questions the situation since everything is working fine.  People
from out of town try to point out the deplorable state of affairs, but are
shrugged off since everything is working fine.

I realize a few posts to the PIClist won't change anything, but I wish there
was a way to slap 10,000,000 programmers and get the world to wake up and
see the damage and cost of the "standard" programming language.

I do all my host programming in Pascal.  I'm not saying that's the Right
Answer either, but it certainly is a lot better.  So are many other
alternatives.  I'm the guy from out of town and can't believe how all the
lemmings of Cland can't see the problem.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\15@100100 by Michael Rigby-Jones

picon face
>-----Original Message-----
>From: RemoveMEpiclist-bouncesKILLspamspammit.edu [piclist-bouncesSTOPspamspamspam_OUTmit.edu]
>Sent: 15 February 2005 14:03
>To: Microcontroller discussion list - Public.
>Subject: RE: [PIC] Bug in Microchip mcc18 std library?
>
>
>
>
>I really wouldn't like the idea of not distinguishing the difference
>between the two types of pointer. They *are* different, and IMHO a
>compiler "hack" to make them compatible is a recipe for disaster.
>
>For a start, rom pointers are *always* const, ram pointers need not be.
>And think of the utter mess of trying to deal with
>pointers-to-pointers,
>ie. void **. Eugh.


In Hitech the only type of pointer that can point to both data and
program memory are pointers to const data types.  Are you saying it's
preferable to have two different functions to deal with pointers to
data/program memory rather than one function that can work with either?
e.g. puts() which is used by printf etc.  As sson as you start splitting
things up like this the compiler moves away from ANSI compatibility and
you have to add all sorts of kludges to get things working.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\02\15@100653 by Herbert Graf

flavicon
face
On Tue, 2005-02-15 at 14:06 +0100, Per Linne wrote:
> Is there a reason you can't use:
>
>  void putrsUSART(const rom char *data)
> {
>   do
>    {  // Transmit a byte
>      while(BusyUSART());
>      putcUSART(*data);
>    } while( *++data );      // <<<<<<<<
>  }

VERY dangerous. Consider what happens if you call with "", you are
checking the location of something pointing beyond the data you passed
in. TTYL


-----------------------------
Herbert's PIC Stuff:
http://repatch.dyndns.org:8383/pic_stuff/

2005\02\15@100931 by Michael Rigby-Jones

picon face


>-----Original Message-----
>From: Olin
>Sent: 15 February 2005 14:47
>To: Microcontroller discussion list - Public.
>Subject: Re: [PIC] Bug in Microchip mcc18 std library?
>

>I do all my host programming in Pascal.  I'm not saying that's
>the Right Answer either, but it certainly is a lot better.  So
>are many other alternatives.  I'm the guy from out of town and
>can't believe how all the lemmings of Cland can't see the problem.

A HHL is only as good as the programmer using it.  It's quite possible
to write completely unmaintainable garbage in Pascal just as you can in
C or virtualy any language.  Assembly language makes writing
unmaintainable garbage a cinch.

Regards

Mike




=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\02\15@102411 by olin_piclist

face picon face
Michael Rigby-Jones wrote:
> A HHL is only as good as the programmer using it.  It's quite possible
> to write completely unmaintainable garbage in Pascal just as you can in
> C or virtualy any language.

True, but C enforces no discipline and makes it much more likely.  Really
good programmers will write good code in any language.  However, most
programmers are surprisingly sloppy.  It's always amazed my how 99% of all
code is poorly written.

Even good programmers make honest mistakes and typos.  You want the language
such that most simple errors cause illegal syntax, not silently substitute
unexpected behaviour.  I wonder how many millions of dollars have been lost
due to IF (I = 1) being written when IF (I == 1) was really intended.  There
is a very real and large cost to C that nobody seems to notice anymore.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\15@102709 by Hulatt, Jon
picon face
> In Hitech the only type of pointer that can point to both data and
> program memory are pointers to const data types.  Are you saying it's
> preferable to have two different functions to deal with pointers to
> data/program memory rather than one function that can work
> with either?
> e.g. puts() which is used by printf etc.  As sson as you
> start splitting
> things up like this the compiler moves away from ANSI
> compatibility and
> you have to add all sorts of kludges to get things working.
>

The ANSI standard C is designed around an architecture which makes no
distinction in memory between data and code space; the PIC isn't like
that. Whilst it's possible to create an ANSI standard compiler for a
PIC, the architectural quirks, IMO, mean that is less than desireable.

Yes, the side effect is the need for different std functions to cope
with different scenarios, but at least that makes the programmer aware
that there is a very real difference.


2005\02\15@105309 by Michael Rigby-Jones

picon face


{Quote hidden}

When you declare data structures you have to tell the compiler if they
are located in program memory or in data memory.  You then have a handy
pointer that can work with either type of data.  Obviously it is a
pointer to a const data type, so the data cannot be modified via that
pointer even if it is in data memory.  The whole idea is that a function
using this pointer dosen't have to be explicitly told where the data is,
it just works.  Wheres the problem exactly?

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\02\15@105533 by Michael Rigby-Jones

picon face


{Quote hidden}

That particular example wouldn't be silent however.  Every compiler I
have ever used will emit a warning if you try to do that, and when
dealing with constant comparisons it can be eliminated by reversing the
arguments e.g. if( 1 == I ).  I understand your point, C gives you a
nice long rope with which to hang yourself.  That same rope is very
handy when used properly though.

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\02\15@110020 by Bob Ammerman

picon face
> In Hitech the only type of pointer that can point to both data and
> program memory are pointers to const data types.  Are you saying it's
> preferable to have two different functions to deal with pointers to
> data/program memory rather than one function that can work with either?
> e.g. puts() which is used by printf etc.  As sson as you start splitting
> things up like this the compiler moves away from ANSI compatibility and
> you have to add all sorts of kludges to get things working.

As long as you have the ability to declare data-constrained and
program-constrained pointers, as well as the 'universal' ones, I guess I am
reasonably comfortable. However, if *every* indirect reference *required*
code to multiplex between code and data, I think I'd find another compiler.

Bob Ammerman
RAm Systems


2005\02\15@111542 by Bob Ammerman

picon face

> When you declare data structures you have to tell the compiler if they
> are located in program memory or in data memory.  You then have a handy
> pointer that can work with either type of data.  Obviously it is a
> pointer to a const data type, so the data cannot be modified via that
> pointer even if it is in data memory.  The whole idea is that a function
> using this pointer dosen't have to be explicitly told where the data is,
> it just works.  Wheres the problem exactly?
>
> Regards
>
> Mike

The problem is that unlike on a PC, for example, the machine language
instructions to access the data in program memory and in data memory are
completely different one from the other. Depending on the PIC, program
memory accesses can be done by using RETLW instructions to define a table,
or via some sort of 'Table Load' instruction. Accessing data memory on the
other hand requires the pointer to be moved into an FSR (and possibly IRP
bits). Constantly checking which is which at runtime is terribly
inefficient. If I wanted that level of performance I'd use Basic ;-) Yech!

Bob Ammerman
RAm Systems




2005\02\15@111603 by ThePicMan

flavicon
face

Olin Lathrop wrote:

>I wonder how many millions of dollars have been lost
>due to IF (I = 1) being written when IF (I == 1) was really intended.

None.. since both produce compile errors.

Since you are putting C under trial, you should at least know that
C statements are case sensitive..


2005\02\15@115529 by olin_piclist

face picon face
ThePicMan wrote:
>> I wonder how many millions of dollars have been lost
>> due to IF (I = 1) being written when IF (I == 1) was really intended.
>
> None.. since both produce compile errors.
>
> Since you are putting C under trial, you should at least know that
> C statements are case sensitive..

OK wiseguy.  I was using case just to make the code stand out from the text
around it, which I suspect you fully understood.  But I'm also not that
familiar with C.  Is it really true that keywords like "IF" are case
sensitive?  In other words, "if" is a keyword and "IF" is an arbitrary
identifier?  That sounds like another set of bugs waiting to happen.

And yes I understand that modern C compilers will flag a warning with "=" in
an IF statement, but I am just trying to illustrate overly lax syntax rules.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\15@122536 by piclist

flavicon
face
On Tue, 15 Feb 2005, Hulatt, Jon wrote:

> However, even without it, my code doesn't work right.
>
> while( *data++ )
> {
>   // Transmit a byte
>   while(BusyUSART());
>   putcUSART(*data);
> }
>
> What the Microchip compiler is doing for that is basically while
> (*(data++)) , so the first char is always missed. My bad. Or is it? I'm
> going to check the text books today to see what the ANSI operator
> precedence should be. I thought that would work.

The problem has nothing to do with operator precedence.  When you
first enter your while loop

while( *data++ )

...you test *data, then increment data.  When you get to
putcUSART(*data), data has already been incremented, and references
the second byte of the string.  I would suggest:

unsigned char ch;

while ((ch = *data++) != 0) {
    while(BusyUSART())
        ;
    putcUSART(ch);
}

This avoids the code size cost of dereferencing the pointer twice.

--
John W. Temples, III

2005\02\15@133009 by Alex Harford

face picon face
On Tue, 15 Feb 2005 11:55:05 -0500, Olin Lathrop
<spamBeGoneolin_piclistspamKILLspamembedinc.com> wrote:
>
> In other words, "if" is a keyword and "IF" is an arbitrary
> identifier?  That sounds like another set of bugs waiting to happen.
>

Compile time error at most, since all variables need to be declared at
the top of a function.

Alex

PS you should have a look at Python for your host side programming,
it's a great language for RAD and has tons of toolkits available for
GUIs, networking, etc.

2005\02\15@134013 by John J. McDonough

flavicon
face
----- Original Message -----
From: "Olin Lathrop" <.....olin_piclistspam_OUTspamembedinc.com>
Subject: Re: [PIC] Bug in Microchip mcc18 std library?


> sensitive?  In other words, "if" is a keyword and "IF" is an arbitrary
> identifier?  That sounds like another set of bugs waiting to happen.

IF is not only an arbitrary identifier, but by convention (but not by rule)
it would be a manifest constant.  It doesn't look anything like if, so it's
hard to see where there is a problem.  What is confusing is when myvariable,
MYVARIABLE,  myVariable, and MyVariable are the same thing.  They don't look
anything alike, and lots of times random case can make things seem to mean
something different.  If they SEEM to mean something different, then they
should mean something different.

I suppose it's all in your upbringing.  A while back I was working over some
Fortran programs, and it was really frustrating dealing with a compiler that
couldn't tell the difference between 0x41 and 0x61.

Very interesting that you are a fan of Pascal, though.  I thought that was
almost extinct.  It's been a long time since I've been much of a fan of the
language for production, but I've always felt that Pascal should be the
first language people learn.  Once someone has been totally immersed in
Pascal it becomes hard for them to write really bad code in any language.

--McD


2005\02\15@135356 by olin_piclist

face picon face
Alex Harford wrote:
>> In other words, "if" is a keyword and "IF" is an arbitrary
>> identifier?  That sounds like another set of bugs waiting to happen.
>
> Compile time error at most, since all variables need to be declared at
> the top of a function.

So are you saying that built in C keywords ARE case sensitive?

*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\15@135526 by piclist

flavicon
face
On Tue, 15 Feb 2005, Olin Lathrop wrote:

> Is it really true that keywords like "IF" are case
> sensitive?  In other words, "if" is a keyword and "IF" is an arbitrary
> identifier?

Yes, it's really true.  All keywords and identifiers are case-sensitive.

> That sounds like another set of bugs waiting to happen.

Such as?  Weren't you earlier bemoaning C's lack of "discipline", yet
you're asserting case insensitivity is "disciplined"?

--
John W. Temples, III

2005\02\15@143215 by olin_piclist

face picon face
John J. McDonough wrote:
> Very interesting that you are a fan of Pascal, though.  I thought that
> was almost extinct.  It's been a long time since I've been much of a
> fan of the language for production, but I've always felt that Pascal
> should be the first language people learn.  Once someone has been
> totally immersed in Pascal it becomes hard for them to write really bad
> code in any language.

Pascal was originally designed as a teaching language, and I think hit the
mark reasonably well.  However, the pure language as defined by Worth and
Jensen was difficult to use.  It had strong type checking (which is usually
a good thing), but no way out for some reasonable cases.  For example, there
was no way to define a subroutine that accepted a variable length array of
32 bit integers, because the number of subscripts was part of the data type
and there was no way to disable that type checking.

I first encountered Pascal at HP in the early 1980s.  Stuff like the array
passing drove me nuts, and I disliked it and stuck mostly to Fortran.  In
1986 I joined Apollo which had created their own variant of Pascal that
solved most of these silly problems.  Most of Aegis (the Apollo operating
system) was written in this Pascal.  I got to like the Apollo
implementation.

A few years later after Apollo I was stuck with the problem of making a
large graphics intensive application that was running on Apollos run on
other workstations.  I knew this was coming, and had envisioned doing a
one-time conversion from Pascal to C and then going forwards in C.  When the
time came, I read the C manual and gagged.  There were so many useful things
I could explain to the Pascal compiler that couldn't be explained to C that
it would have been a giant step backwards for the code base.

Instead we decided to write a translator that would translate the Pascal to
whatever the best language was on each target system, compile in that
language, then throw out the intermediate source and keep the binary.  This
worked very well.  In the end it turned out to be very useful to have a
translation step between our code and the code the end compiler got,
regardless of converting between languages in the process.  Each of the
target compilers had its own bugs and slightly different ways of dealing
with some system issues.  We could implement work arounds for these issues
in the translator back end.

In the process we also extended the Apollo Pascal definition in some places
and ignored other parts.  Most of these differences were to support writing
portable code accross different machine and operating system types.

I've continued writing in Pascal and using the translator ever since.  The
translator is called SST, and is actually included in the PIC programmers
development software release at http://www.embedinc.com/picprg/sw.htm.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\15@144023 by olin_piclist

face picon face
piclist@xargs.com wrote:
> Such as?  Weren't you earlier bemoaning C's lack of "discipline", yet
> you're asserting case insensitivity is "disciplined"?

It depends on how you think of it.  Good syntax rules make it more likely
that minor typos become illegal, and that casual observers won't be misled.
Case sensitivity is just asking for someone to create two variables called
BigOats and BiGoats.  I can also see how "IF" versus of "If" could get
easily missed by a reviewer.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\15@150642 by Robin Abbott

flavicon
face
Well our compiler allows pointers to freely point to ROM or RAM by using
the top bit to show ROM or RAM. Of course that means a maximum of
32Kwords of ROM can be addressed by the ROM pointer. We handle this by
putting all constant data in the bottom 32K of ROM and allowing the user
to define functions to which pointers must be created as "pointed". This
is only necessary on devices with more than 32K words of ROM.

I happen to think that having to call 2 versions of every function
dependant on whether a pointer is to ROM or RAM is very messy.

Robin Abbott

Forest Electronic Developments

01590 681511
+44 1590 681511 (phone/fax)

See our web pages : http://www.fored.co.uk



{Original Message removed}

2005\02\15@152201 by Rob Young

picon face
> Alex Harford wrote:
>>> In other words, "if" is a keyword and "IF" is an arbitrary
>>> identifier?  That sounds like another set of bugs waiting to happen.
>>
>> Compile time error at most, since all variables need to be declared at
>> the top of a function.
>
> So are you saying that built in C keywords ARE case sensitive?
>

They are case sensitive.  However it is possible that a compiler's author(s)
could have been lazy and don't care about "if" vs "IF" vs "If" vs "iF"...

Likewise, "BigOat" is different from "BiGoat" because variables are supposed
to be case sensitive.  But again, a lazy compiler writer might ignore the
differences.

There are compiler dependent differences in how many letters are actually
used from the variable name.  It has been my experience that at least the
first 64 are reconginzed by the "major" players in C compilers.  And unless
you are a hopeless Hungarian Notation freak, how often are your variable
names longer than 64 characters anyway?  Personal opinion, but if you need
more than 64 characters to describe your variable or object, seek help.

Rob Young

2005\02\15@152209 by D. Jay Newman

flavicon
face
> So are you saying that built in C keywords ARE case sensitive?

All identifiers in standard C are case sensitive.

On the other hand, I prefer languages to be case insensitive *and*
case preserving. This is much like the file systems on Windows and Macintosh
computers. It is also closer to how people think. Case is an artifact of
some forms of writing.
--
D. Jay Newman           ! Polititions and civilations come and
TakeThisOuTjay.....spamTakeThisOuTsprucegrove.com     ! go but the engineers and machinists
http://enerd.ws/robots/ ! make progress

2005\02\15@152405 by Marcel van Lieshout

flavicon
face
I couldn't agree more. I am currently porting an rtos from mcc18 to wizC and
I must say it's a joy the way things are handled by Robin's compiler.

Robin Abbott wrote:
{Quote hidden}

> {Original Message removed}

2005\02\15@154021 by piclist

flavicon
face
On Tue, 15 Feb 2005, Olin Lathrop wrote:

> Case sensitivity is just asking for someone to create two variables called
> BigOats and BiGoats.

And how is this different from BigOats vs. Big0ats in a
case-insensitive language?  The fact that you *can* create variables
with confusing names doesn't meant you're going to *accidentally* do
so.  Bad practice transcends language.

But if a language lets me randomize the spelling of BigOats, I've
simply added a confusion factor for a reviewer since I'm not required
to be disciplined in my capitalization.

> I can also see how "IF" versus of "If" could get easily missed by a reviewer.

I don't think anyone is going to be reviewing code that hasn't been
compiled, and "IF" vs. "If" is not going to be missed by a compiler.

--
John W. Temples, III

2005\02\15@163009 by James Newton, Host

face picon face

> > Case sensitivity is just asking for someone to create two variables
> > called BigOats and BiGoats.
>
> And how is this different from BigOats vs. Big0ats in a
> case-insensitive language?  The fact that you *can* create
> variables with confusing names doesn't meant you're going to
> *accidentally* do so.  Bad practice transcends language.

For anyone who missed it, the second variable name above has a zero in it.

I try to make sure I program in a font that differentiates between 0 and O,
l and 1, 5 and S, and has enough space between the letters to prevent
confusing rn with m.

For what it's worth, case sensitivity is just a way for a compiler (and its
author) to do less work. As much as it pains me to say it, the IDE for
Visual Basic is fantastic and handling this... Are any of the PIC IDEs like
that?

This thread is very nearly not PIC related...

...if we continue with language wars, I would appreciate it if the tag
changed to [EE].

---
James Newton: PICList webmaster/Admin
TakeThisOuTjamesnewtonKILLspamspamspampiclist.com  1-619-652-0593 phone
http://www.piclist.com/member/JMN-EFP-786
PIC/PICList FAQ: http://www.piclist.com



2005\02\15@165421 by Wouter van Ooijen

face picon face
> Yes, it's really true.  All keywords and identifiers are
> case-sensitive.
>
> > That sounds like another set of bugs waiting to happen.

No, I have never seen a problem related to the case-sensitiveness of the
keywords. Not even in beginners' code.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\15@165421 by Wouter van Ooijen

face picon face
> >I wonder how many millions of dollars have been lost
> >due to IF (I = 1) being written when IF (I == 1) was really intended.
>
> None.. since both produce compile errors.
>
> Since you are putting C under trial, you should at least know that
> C statements are case sensitive..

Hmmmmm. Perfectly vaild but very pointless remark. The above *is* a
major problem in C. But most C *compilers* will at least give a warning.
Provided that the compiler does not also produce a mess of useless
warnings, this mostly solves the problem.

C is a lot like the PC architecture or the 14-bit PIC architecture: a
total mess, but so bloody cheap and easily available that you will
probably want to use it regardless.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\15@165421 by Wouter van Ooijen

face picon face
> You seem to be thinking I was talking about C versus assembler

I was mainly have fun. I think most C programmers are well aware of the
problems of the language, but in a lot of cases those problems still
outweight the advantages (or rather: the alternatives have more
problems).

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\15@165422 by Wouter van Ooijen

face picon face
> That's pretty much what i've now decided to do.
>
> I did previously get the LCD lib working (with an lcd you supplied me,
> no less!), but to have to recompile the libraries to match
> the pin/port
> configuration you're using seems a bit c**p to me.

That's why I never use object libraries. In my main file I put some
#defines that define the pins used, next I include the library source.
(yes: #include <lcd.c>). This is against the lore, but that lore was
established when computer memories were small, recompilation took a lot
of time, and the linker was much faster than the compiler. Times have
changed.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\15@190820 by olin_piclist

face picon face
James Newton, Host wrote:
> For what it's worth, case sensitivity is just a way for a compiler
> (and its author) to do less work. As much as it pains me to say it,
> the IDE for Visual Basic is fantastic and handling this... Are any of
> the PIC IDEs like that?

At least with MPASM you can disable case sensitivity.  I always use it with
case sensitivity disable.  It saves a lot of messing with the SHIFT key to
type SFR names, which are all defined in upper case in the standard include
files.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com

2005\02\16@002832 by William Chops Westfield

face picon face
On Feb 15, 2005, at 8:55 AM, Olin Lathrop wrote:

> I am just trying to illustrate overly lax syntax rules.
>
Almost all languages have ways to shoot yourself in the foot.
Languages that have gone to a lot of trouble to eliminate such
foot-shooting-mechanisms have found themselves rejected and
ridiculed  (I'm specifically thinking of Ada here, but the pascal
variants like modula2 come close too, I think.)

It HAS been amusing to watch C "take over the world" in spite
of all those other efforts.  I can only conclude that somehow
C managed to hit the 'sweet spot' of the power/danger curve.

To be fair, its worth pointing out that a lot of C's current
usefulness seems to come from breaking assumption of the original
language in favor of greater safety.  The latest versions of
compilers check printf arguments against the formatting string,
despite the fact that that is deep library knowledge, not only
not part of the C language, but not SUPPOSED to be part of the
language.  But still useful :-)

BillW

2005\02\16@052041 by Jan-Erik Soderholm

face picon face
Olin Lathrop wrote :

> At least with MPASM you can disable case sensitivity.  I
> always use it with case sensitivity disable.  It saves a
> lot of messing with the SHIFT key to type SFR names,
> which are all defined in upper case in the standard include
> files.

Right, after removing the double defined (upper *and* lower
case) SFR names in some of the device include files... :-)

Jan-Erik.



2005\02\16@071040 by Peter L. Peres

picon face


On Tue, 15 Feb 2005, Per Linne wrote:

{Quote hidden}

That code fails if the first character is NUL

Peter

2005\02\16@082950 by Per Linne

flavicon
face
I know I know... Thank you all.

My point was the OP:s reasoning about post increment.
I thought that noone seemed to point out the existence of
the pre increment alternative. My intention was not to provide
the perfect solution to the problem. On the other hand why would
anyone write a null string to a function in an embedded application.
But of course: Better safe than sorry...

After all I got the impression that it started out with M:chips
mcc18 std library and it suffers the same pitfall when it comes
to null strings. Doesn't it.

Regards,
PerL

PS 70 percent of my (full) time I write C and C++ programs and
have a few products out there. Of course I make misstakes and
ugly fast things now and then. And sometimes I have to trace
bugs to. That bad am I. :-)


{Original Message removed}

2005\02\16@155606 by Peter L. Peres

picon face


On Tue, 15 Feb 2005, Olin Lathrop wrote:

> OK wiseguy.  I was using case just to make the code stand out from the text
> around it, which I suspect you fully understood.  But I'm also not that
> familiar with C.  Is it really true that keywords like "IF" are case
> sensitive?  In other words, "if" is a keyword and "IF" is an arbitrary
> identifier?  That sounds like another set of bugs waiting to happen.
>
> And yes I understand that modern C compilers will flag a warning with "=" in
> an IF statement, but I am just trying to illustrate overly lax syntax rules.

Imho the only bug in C is that it has a stoopid string end encoding
convention that supplies about 50% of the proverbial rope to pointer &
string users.

As to confusing C code, there is a contest for 'obfuscated C'. The
following code is a BASIC interpreter (!) that won first prize once. I
took a few hours to pick it apart once. Most instructive code. Obviously
one is not supposed to code like that ;-)

Code by Diomidis Spinellis:
-- start --
#include <stdio.h>
#define Q r=R[*p++-'0'];while(
#define B ;break;case
char*s="Qjou!s\\311^-g\\311^-n\\311^-c\\::^-q-ma%mO1JBHm%BQ-aP1J[O1HB%[Q<nbj\
o)*|gps)<<*txjudi)m*|aQdbtf!::::;sfuvso<aQefgbvmu;aQ<m,,a%CQ<csfbla%bQ<aN2!Q\
\ndbtf!aP2Q;m>aP2Q<a%!D12J!JGJHJOJQJFJSJJJMHS%HD12D12N3!N4\nJUJT%UQm>aP4HC%T\
Qs\\q,,^>m,2<m>aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQUaP1H\
R%PN4\nQ<g\\(aP3Q(^>aP2Q,2<n\\(aP3Q(^>aP4Hb%OD12D12N2!N3\nJVP3Q,,<jg)aP3Q=>n\
\\(aP3Q(^*m>g\\(aP3Q(^<fmtf!m,,aHC%QN1!N1\nJ#Qqsjoug)#&e]o#-aP1Q*aHb%#Qqvut)\
aP1Q*aHb%FN1\nQm>::::aHC%VP3Q>bupj)hfut)c**aHb%JD12JON1!Qjg)a%LN1UP1D12JIQUa\
P1HL%IQ*m>aN2!N2\nP2Q<fmtf!m,,aHC%MN1!N2>P2Q>aN2\nP2Hbdd!b/d";k;char R[4][99]
;main(c,v)char**v;{char*p,*r,*q;for(q=s;*q;q++)*q>'
'&&(*q)--;{FILE*i=fopen(v[1],"r"),*o=fopen(q-3,"w");
for(p=s;;p++)switch(*p++){B'M':Q(k=fgetc(i))!=EOF
&&k!=*p)*r++=k;if(k==EOF){fputs("}}\n",o);fclose(o);return
system(q-6);}*r=0B'P':while(*p!='`')fputc(*p++,o)B'O':Q*r)fputc(*r++,o);p--B'C':k=0
;Q k<*p-'0')(*r++=fgetc(i),k++);*r=0 B'I':k=*p;if(**R==k)goto G B'G':k=*p;
G:p=s;while(*p!='$'||p[1]!= k)p++;p++B'N':R[*p-'0'][0]++;}}}
--end--

(this rendering does not do the original justice, the original was a
compact block of text, my MUA broke it up, so this version probably
won't compile easily)

When compiled, the program correctly interprets a game called LANDER.BAS
which you can find on the internet. You can find more references by
looking for 'obfuscated c' in a search engine.

Peter

2005\02\16@162038 by Peter L. Peres

picon face


On Tue, 15 Feb 2005, Olin Lathrop wrote:

> Alex Harford wrote:
>>> In other words, "if" is a keyword and "IF" is an arbitrary
>>> identifier?  That sounds like another set of bugs waiting to happen.
>>
>> Compile time error at most, since all variables need to be declared at
>> the top of a function.
>
> So are you saying that built in C keywords ARE case sensitive?

ALL identifiers *and* keywords (there exactly 32 keywords in C - C is a
RISC language in a way) are case sensitive. Additionally, you cannot use
ANY keyword as an identifier, ever.

Peter

2005\02\16@162433 by Peter L. Peres

picon face


On Tue, 15 Feb 2005, Olin Lathrop wrote:

> .....piclistspamRemoveMExargs.com wrote:
>> Such as?  Weren't you earlier bemoaning C's lack of "discipline", yet
>> you're asserting case insensitivity is "disciplined"?
>
> It depends on how you think of it.  Good syntax rules make it more likely
> that minor typos become illegal, and that casual observers won't be misled.
> Case sensitivity is just asking for someone to create two variables called
> BigOats and BiGoats.  I can also see how "IF" versus of "If" could get
> easily missed by a reviewer.

The reviewer is usually lint (a C source checker). It, and the
compiler's built-in syntax checking will locate most errors. Also, there
is no such thing as an automatically allocated variable name in C. Each
variable name is declared by the user and its scope is strictly
controlled, inside a paragraph of source, a function, local to a
specific source file, or to the whole program.

Peter

2005\02\16@163629 by Wouter van Ooijen

face picon face
> Imho the only bug in C is that it has a stoopid string end encoding
> convention that supplies about 50% of the proverbial rope to
> pointer & string users.

That's only 10% a C language feature, and 90% a C *library* feature. It
has no influence on pointer use except for pointers into 0-terminted
strings. And if you consider that the biggest problem in C your
definitely on your own. Come to my classes and assist me to help the
students with all the other nice features of C!

And if you want to read a real expert check
www.amazon.com/exec/obidos/ASIN/0201543303/103-1785716-4999000.
But note that even though he disliked a lot about C he changed nearly
nothing in the extension to C++.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2005\02\16@231237 by Bob Ammerman

picon face
> ALL identifiers *and* keywords (there exactly 32 keywords in C - C is a
> RISC language in a way) are case sensitive. Additionally, you cannot use
> ANY keyword as an identifier, ever.
>
> Peter

Unless you do the utterly reprehensible thing of #defining them to something
else :-)


#define if  aa

int if = 10;

while ( if-- )
   n += if;


Evil, huh?

Bob Ammerman
RAm Systems


2005\02\17@140657 by Peter L. Peres

picon face


On Wed, 16 Feb 2005, Bob Ammerman wrote:

{Quote hidden}

That assumes that no if is used as a keyword in the program, no ?

Peter

More... (looser matching)
- Last day of these posts
- In 2005 , 2006 only
- Today
- New search...