XC8 novice question

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Novice question using MPLABx + XC8




If i define my_variable using;

#define my_variable 0b10000000


And then I use it in a function that expects a 'char';

void my_function(char i);



I get a compiler warning;

warning: (752) conversion to shorter data type




By changing the function prototype to expect an 'int' the warning goes  
away so I think the defined my_variable is being assigned as an 'int'


So my question is how or can I structure my define so the defined  
my_variable is assigned as a 'char'..


I cannot see anything useful in the mplabx documentation.

Thanks.




Re: XC8 novice question
On 9/11/2016 12:02 AM, rwood wrote:
Quoted text here. Click to load it

Why not explicitly cast the value to a "char" in the define-ition
(*if* you expect to always use it as such)?

Note that you should decide if you do/don't care about signedness
of the value (i.e., is this value 128 or -127?) as "char" can vary
from implementation to implementation.

Re: XC8 novice question
On 11-Sep-16 5:55 PM, Don Y wrote:
Quoted text here. Click to load it


Hi Don, I tried using:

        #define my_variable (char)0b10000000

and also:

        #define my_variable ((char)0b10000000)


Both of which compile without issue but still the warning  about  
converting to a shorter data type persists.

Thanks.



Re: XC8 novice question
On 11/09/16 12:25, rwood wrote:
Quoted text here. Click to load it

I suspect that on your system, "char" is signed by default.  When you  
write a number like 0b10000000, it is an "int" (unless it is outside the  
range of "int", in which case it gets bumped up to the first match of  
unsigned int, long int, unsigned long int, long long int, unsigned long  
long int).  By casting it to "char", you are asking the compiler to fit  
the value 128 into a type with a range -128 to 127 (assuming I am right  
that char is signed on your system).  That is causing the warning.

Never use "char" for numbers.  It is /always/ the wrong type - its  
signedness will vary from system to system, and the name does not match  
the usage.  And if your code might be used on other systems, remember  
that on some DSPs "char" is not 8 bits.  Use "uint8_t" or "int8_t" as  
appropriate for numbers (or "uint_least8_t" and "int_least8_t" for very  
portable code).

So:

    #define my_variable ((uint8_t) 0b10000000)
    void my_function(uint8_t i);


Also consider:

    static const uint8_t my_variable = 0b10000000;

instead of the #define, unless you really need it to be a #define'd  
value (such as to give the size of an array, or because you have a crap  
compiler).




Re: XC8 novice question
On 9/11/2016 4:35 AM, David Brown wrote:
Quoted text here. Click to load it

A drawback to this approach is it allows the OP to continue to think
of it as a "variable".  Either rename it ("my_constant" or "MY_CONSTANT")
or use a manifest constant so each reference is ACTUALLY replaced with
the PREPROCESSOR SUBSTITUTION:
      MY_CONSTANT = 7;  (wrong!)
becomes:
      128 = 7;
(which is CLEARLY wrong!)

[Time for bed...]



Re: XC8 novice question
On 11/09/16 16:32, Don Y wrote:
Quoted text here. Click to load it

Well, clearly he needs to pick a better name for his "variable".  I  
don't know if he just picked a bad name, or if he is confused about  
variables and constants.

But if "my_variable" is declared as a "const", then writing "my_variable  
= 7" will give a compile-time error just as surely as it would with a  
pre-processor symbol.


Re: XC8 novice question
On 9/11/2016 7:58 AM, David Brown wrote:
Quoted text here. Click to load it

Yes, but IME much easier to see whay you've done wrong (looking at the
cpp(1) output).

Similar to writing:
     if (4 == count)...
instead of:
     if (count == 4)...

Re: XC8 novice question
On 11/09/16 22:15, Don Y wrote:
Quoted text here. Click to load it

Well, there may be differences of opinion here - and certainly
experience and preferences are personal, making it hard to say "you are
wrong".

But you are wrong.

Writing "if (4 == count)" is wrong.  The last thing you need in your
code is to write it backwards - it messes with your thinking, your
writing, your reading and your understanding.

There are only three reasons why you would want to write "if (4 ==
count)".  Either /all/ of these are true:

1. You have trouble writing correct C code, even with the basic stuff
(noting that everyone starts out as a beginner).
2. You have a very poor quality compiler that can't check for such mistakes.
3. You can afford to make mistakes and produce broken code, but can't
afford software such as PC-Lint (or just gcc) to check such mistakes.
4. You have no code reviews or other code quality control.
5. You don't test your code, so don't see the consequences of the mistake.

/or/

You are required to program to a coding standard designed by numpties
who make the assumptions above (i.e., MISRA - a mixture of good but
mostly obvious ideas and a selection of downright bad ideas left over
from the 90's).

/or/

You are small and green, and rely on the force.  And when 900 years old
/you/ are, speak normally /you/ will not.



No one looks at the C pre-processor output.  There is no advantage in an
error that could be found by look at it.  If you declare your constant
values as "const", then the compiler will stop with an error if you try
to assign to them after initialisation.  The error will be in the
obvious place, and will be clear - you don't get better than that.


Re: XC8 novice question
On 9/11/2016 11:55 PM, David Brown wrote:
Quoted text here. Click to load it

No, the answer is much simpler than any of that!

I started writing code in C (almost exactly) 40 years ago.  Owning
my first "personal" SysV machine more than 30 years ago.

Compilers "back then" were far less "helpful" than what folks
are used to using, today.  And, far less "accessible" (imagine
writing your code on a piece of PAPER and frantically typing
it in when you get a chance -- so you can actually RUN it a few
times, TODAY).  Does your pen/paper "run lint"?

[Do you remember when C didn't have a "void" type?  Or, using '\!'
and '\!!' in your sources?  Or, when members of one type of
struct had to have different names from any members of any
OTHER structs (i.e., all tags shared a SINGLE namespace)?]

And, over the years, have collected a bunch of compilers for
oddball processors where the capabilities are essentially
"take it or leave it -- no one else HAS a compiler for this
processor!".  If all your development has been for mainstream
products, you're probably "spoiled" by the tools available!

I would NOT, for example, write:
     x=-1;
And, I *would* write:
     p = &buffer[0];
I'd use parens in places that you'd consider superfluous -- but that
made bindings very obvious (cuz the compiler would do what I *told* it
without suggesting that I might be doing something unintended):
     y = x / (*p);
     (*f)();
Or, lengthy expressions laid out as:
     foo = ( a + b )
         / ( c * d )
         - ( e % f );

And, to catch (some) '=' instead of "==" errors, write tests as:
     if ( CONSTANT == expression ) ...

[would you consider "if (foo==bar())" as preferred to "if (bar()==foo)"?]

Much of this is a consequence of how I learned to "read" (subvocalize)
code to myself:
     x = y;
is "x gets the value of y", not "x equals y".  (how would you read x ::= y ?)
     if ( CONSTANT == expression )
is "if expression yields CONSTANT".  Catching myself saying "if CONSTANT gets
expression" -- or "if variable gets expression":
     if ( CONSTANT = expression )
     if ( variable = expression )
is a red flag that I'm PROBABLY not doing what I want to do.

I'll wager that most folks read:
     x = y;
as:
     x equals y
and subtly change their intent, but NOT their words, when encountering:
     if ( x == y )
as:
     if x equals y
(how would they read "if ( x = y )"?)

People reading my code never seem to have any problem understanding
that:
    if ( NULL == malloc(...) )
is testing for a NULL result from malloc (i.e., "malloc yielding NULL").

[They also don't seem to find parallel loading a (hardware) counter with
0 as the same as "clearing" it.]

This sort of "reading" makes it easy to discuss:
      (x, y) := cursor_position();
("instantiate an x,y tuple with the current cursor position") vs.
      (x, y) = cursor_position();
("the x,y tuple gets the current cursor position") or:
      x = cursor_X_coordinate();
("x gets the cursor's X coordinate")

What's important is consistency.  It takes very little time for someone to
pick up on a particular style -- if it is used CONSISTENTLY throughout a
document/project.  Ever notice code that walks an array using an index
into the array; then, somewhere else, a pointer into it?  As if the
decision was arbitrary (or, made by someone other than the original
developer -- having a different style?)  Or, that refers to screen coordinates
as "(x,y)" in some places, "(row,column)" in others (did you notice that
row,column is really y,x?) and "(r,c)" in still others?

You can read my code over the years and see the same style propagated
throughout (discounting changes to the language, as alluded to earlier).
It doesn't change when the "style du jour" comes -- and goes! -- along
the way!  (though identifiers have lengthened as the tools have supported
them)


Re: XC8 novice question
On 12/09/2016 10:41, Don Y wrote:

<snip>

Quoted text here. Click to load it

This is why I now write to this form. As someone who also writes VHDL  
where a single '=' is used in a conditional statement, it's all too easy  
to forget the '==' when reverting back to writing C.

If, by accident, I write in 'c'
    if ( CONSTANT = expression )
I get a compiler error rather than getting entirely different behaviour  
to that intended.

It is a style often recommended for safety critical applications.

--  
Mike Perkins
Video Solutions Ltd
We've slightly trimmed the long signature. Click to see the full one.
Re: XC8 novice question
On 12/09/16 14:16, Mike Perkins wrote:
Quoted text here. Click to load it

If you write "if ( CONSTANT = expression )" by mistake in C, you get a
compiler error.  If the constant is not actually a constant, but a
variable, you get a warning.

Quoted text here. Click to load it

No, it is a style recommended by people who think other people don't
understand their tools properly.

People writing safety critical applications will not make such mistakes
because:

1. They are careful when writing their code.

2. They use as much static error checking as practically possible.  That
will always catch such errors.

3. They don't intentionally write code that looks like a mistake (such
as "if (x = getNextItem()) ..." that might trigger warnings.

4. They have code reviews to help spot errors.

5. They have comprehensive testing.

6. They do not write code that reads backwards.

7. They do not rely on a rule like writing your conditionals backwards,
which fails to work if the "constant" part is not actually declared
constant.  They prefer to rely on rules that actually /work/, such as
requiring appropriate compiler static error checks.

I'm all in favour of "defensive programming", and  multiple defences to
stop errors creeping in.  But this particular case is just silly.


Re: XC8 novice question
On 12/09/2016 13:56, David Brown wrote:
Quoted text here. Click to load it

Oh dear. We're all careful in writing code. The more careful, the less  
code. A bit like people who don't make any mistakes.

Quoted text here. Click to load it

Yes, they might give you a warning in the case "expression = CONSTANT"  
to see if that was intended.

Quoted text here. Click to load it

As above.


I would hope that no such serious issues get this far.

Quoted text here. Click to load it

Of course.


No. If it takes a second look for a reviewer to see what is intended, it  
can only make for safer code.

Quoted text here. Click to load it

It's not a rule, its a style which is intended to remove silly errors.

Quoted text here. Click to load it

Oh good, yet you seem to take a dislike to to others' defensive styles  
and methods. Is your way the only one everyone else must conform to?

--  
Mike Perkins
Video Solutions Ltd
We've slightly trimmed the long signature. Click to see the full one.
Re: XC8 novice question
On 12/09/16 15:33, Mike Perkins wrote:
Quoted text here. Click to load it

I've seen more than enough code from different people to know that not
everyone is careful when coding!

Quoted text here. Click to load it

Exactly.  And usually you can choose to treat such warnings as errors.

Quoted text here. Click to load it

Yes, "if (x = getNextItem())" will trigger the same warning.  Style
guides for safe programming often ban (or at least advise against)
having expressions with side effects inside a conditional like this.

If you /really/ want to write code like that, most compilers/linters
will drop the warning if you use double parenthesis:

    if ((x = getNextItem())) ...


Quoted text here. Click to load it

That's what static error checking is for - catch the errors as early as
possible.

Quoted text here. Click to load it

I am happy with some defensive styles, unhappy with others.  If the
"defence" makes code harder to follow in some way, and does not add
noticeably to the safety, then it is a bad idea.  It is that simple.

In this particular case, writing "if (1 == x)" instead of "if (x == 1)"
adds absolutely /nothing/ to the "defence", if you already have sensible
safe programming rules in place.  And if you don't have such rules in
place, this particular rule is a drop in the ocean at best, and false
security at worst.

Thus there is no defensive advantage in it.

And while I am happy to accept that "code clarity" and "ease of
understanding" are highly subjective issues, I think "if (1 == x)" reads
backwards.  It hinders comprehension.  It might not hinder it much, but
it hinders it a little.

Thus there is a clear disadvantage to it.

So I have no doubts that the "if (1 == x)" style is a bad idea overall.


Any rule or style guideline should be considered in this way to see if
it is a good idea or not.  And the results are going to vary from
programmer to programmer and project to project.  If /you/ do your
cost-benefit analysis and feel that "if (1 == x)" is a positive rule
overall, then that's fine for you.  It would surprise me, but that's fine.



Re: XC8 novice question

tto:

Quoted text here. Click to load it

not always, it depends on the compiler.

Bye Jack

Re: XC8 novice question
On 12/09/16 16:50, Jack wrote:

Quoted text here. Click to load it

Yes, I know.  If your compiler is not good enough to catch basic errors  
like this, it is wise to use an additional static error checker such as  
PC-Lint, splint, or simply use gcc or clang for a different target (you  
are not interested in the output, merely the error messages and warnings).

Note that you also need to know how to use your compiler, and how to  
enable such warnings - most will not warn much by default.


Re: XC8 novice question
David Brown wrote:
Quoted text here. Click to load it
<snip>
Quoted text here. Click to load it


It's a harmless, free-floating heuristic. "Free-floating" in that , as  
you note, there may be other mechanisms for catching this.

<snip>

--  
Les Cargill

Re: XC8 novice question
On 9/12/2016 5:16 AM, Mike Perkins wrote:
Quoted text here. Click to load it

On a daily basis, I use:
    foo = bar
    foo := bar
    foo == bar
all as variants of what some would read as "equals".

I don't want to be casual in what I type.  And, I don't want folks
reading it to be casual in what they read:  what EXACTLY is he saying, here?
Why the colon?  Why the extra '='?  Why *not* a colon/extra '='?

It's far too easy to see what you WANT to see when "proofreading".
And, for folks who've been coerced into performing a function
(e.g., not many folks are eager to participate in a code review:
"*MY* code isn't getting written while I'm sitting here CHECKING YOURS!"),
there's even less incentive to "read carefully".

Quoted text here. Click to load it

Often, safety critical (and other "regulated" application domains)
have few compiler releases.  Because the compiler must be formally
certified/qualified.

So, you don't benefit from the most recent product offerings of
company's X, Y and Z.  And, you almost surely never get a chance
to recompile code just to see how it behaves with the NEW code
generator.

You probably won't even be allowed to bring the tool on-site
out of fear that it will be used and its use not discovered
before product has been affected.  "Are we SURE these libraries
weren't compiled with that ALIEN compiler?"  And, you're
probably not likely to be allowed to take The Company Jewels
home with you so you can test them on YOUR (uncertified)
compiler:  "Just to see what it says about the code"

"Trust me, Mr Casino Operator, my tools didn't generate machine
code that was ANY different from the code that was generated by the
APPROVED compiler.  Then why did I use it if the binaries are
exactly the same?  <shrug>  I wanted to see if it produced any
warnings that the other compiler didn't...  Oh, you want me to PROVE
that the output is identical?  By running it through the APPROVED
compiler for the deliverable??"

Re: XC8 novice question
On 12/09/16 11:41, Don Y wrote:
Quoted text here. Click to load it

Yes, long ago compilers had little in the way of helpful warnings or
checks.  And long ago, lint was not as good (though it's history is
nearly 40 years old), and not as easily available.

But /today/, there is no reason not to have reasonable error checking
and warnings on your compiler.  And if you compiler doesn't do a good
enough job by itself, you can use PC-Lint, splint, or even gcc/clang for
a different target in order to get good checking.  (It's not needed here
- XC8 will report "if (count = 4)" errors.)

Quoted text here. Click to load it

The earliest C I have worked with is C89/C90/ANSI.  It is fortunately
rare that I have to work with such old tools, and I think it would be
madness to limit my modern programming to suit such tools.

Quoted text here. Click to load it

I have products for which there are /no/ decent C compilers, or at least
products that could never have been made if we used the available
compilers.  And I have products where the only choices are poor or
limited compilers.  But for the most part, quality of tools is an
important criteria when choosing a microcontroller.

Quoted text here. Click to load it

Neither would I - I would write "x = -1;".  But I believe I am missing
your point with this example.

Quoted text here. Click to load it

So would I - because I think the code looks clearer.  When I want p to
be a pointer to the first element of "buffer", that's what I write.

Quoted text here. Click to load it

Me too.  But that's for clarity of code for both the reader and the
writer - not because I worry that my tools don't follow the rules of C.

Quoted text here. Click to load it

Me too.


I'd write

    f();

Though I'd use a better name than "f" for a function pointer, and I try
to avoid function pointers where possible.

Quoted text here. Click to load it

If the expression were complicated enough, I would write:

    int x = a + b;
    int y = c * d;
    int z = e % f;
    foo = x / y - z;


Quoted text here. Click to load it

No, I would /never/ write that.  I would write it in a way that makes
logical sense when reading or writing.  You would say "if the number of
apples is 3, the price is $1" - you would never say "if 3 is the number
of the apples, $1 is the price".

Thus I would always write:

    if (expression == constant) { .... }

(I'm not a fan of shouting either - I left all-caps behind with BASIC
long ago.)

What benefit do you think "if (CONSTANT == expression)" gives you?  Why
is it useful to invert the logic and make code hard to read, just in
case you make a mistake and write "if (expression = CONSTANT)"?  It is
highly unlikely that you would make such a mistake, and even less likely
that you would make it and not find it quickly - and you compiler (or
linter) will spot it for you.

Quoted text here. Click to load it

I'd usually try to avoid a function call inside an expression inside a
conditional, but if I did then the guiding principle is to make it clear
to read and understand.

Quoted text here. Click to load it

I can't say I vocalize code directly - how does one read things like
brackets or operators like -> ?  But "x = y" means "set x equal to y".

Quoted text here. Click to load it

"if x equals y", or "if x is equal to y".

Quoted text here. Click to load it

I read it as "warning: suggest parentheses around assignment used as
truth value" :-)

It's simply a mistake, and I would not read it at all without mentioning
the error.

Quoted text here. Click to load it

Certainly people will know what the code does.  That does not mean it is
the clearest choice of code for the job.

Quoted text here. Click to load it

My code style has been fairly similar over the 20 years I have been
professionally programming C, as the guiding principles have been
consistent.  But a number of aspects have changed over time - when a
change of style has made sense and led to better or clearer code, I have
made that change.  And when newer and better tools or language features
have allowed better or clearer code, then I have embraced those features
and changes.  I certainly don't believe I started my career with a
perfect style that must be maintained for ever.

Consistency is a good thing - there's no doubt there.  But it is not the
overriding concern in all cases - breaking with old habits is necessary
in order to improve.


And remember, in this thread and context, we are giving advice to a new
programmer.  It is one thing to say that /you/ want to write "if (4 ==
count)" to remain consistent with the vast quantities of code you have
written over the last 40 years.  It is entirely different to consider
how this /new/ programmer should write the vast quantities of code he
will produce over the /next/ 40 years.  /You/ have to live with the
decisions from your past - the new programmer does not.



Re: XC8 novice question
On 9/12/2016 5:35 AM, David Brown wrote:
Quoted text here. Click to load it

Try 10 years earlier.  Try writing on a PDP-11 that you
SHARED with others (including PAYROLL!)

Quoted text here. Click to load it

My example would be parsed as:
    x =- 1 ;
Nowadays, you would see this as:
    x -= 1 ;
Would you have noticed that it was NOT assigning "-1" to x?
Would you have wasted that precious, limited timeslot that you
had access to "The Machine" chasing down a bug that you could have
avoided just by adopting a style that, instead, writes this as:
    x = -1;

Quoted text here. Click to load it

You'll more frequently encounter:
      p = buffer;

Quoted text here. Click to load it

The problem isn't that tools don't follow the rules.  The problem is that
a compiler can be conforming WITHOUT holding your hand and reminding you
that what you've typed *is* "valid C" -- just not likely the valid C
that you assumed!

Quoted text here. Click to load it

Because the compiler would gladly think "y=x/*p;" was THREE characters
before the start of a comment -- without telling you that it was
interpreting it as such.  Again, you turn the crank and then spend
precious time staring at your code, wondering why its throwing an error
when none should exist (in YOUR mind).  Or, worse, mangling input:

         y=/*p      /* this is the intended comment */
           x=3;

seen, instead, as (error-free!):

         y=x=3;

Quoted text here. Click to load it

If the bag yields 3 apples...

Quoted text here. Click to load it

I ALWAYS use caps for manifest constants.

Quoted text here. Click to load it

Again, you're spoiled by adopting C when it was far more mature
and had more mature tools as well as accessibility.  Give yourself
an hour, today, to use your PC/computer.  See how much work you get
done (lets forget that your computer is 1000 times more capable).
But, don't fret; whatever you DON'T get done you can tackle
tomorrow -- in THAT 1 hour timeslot!

Quoted text here. Click to load it

Which do you claim is cleared?
Imagine foo is "errno".
After answering, rethink it knowing that errno is actually a function
invocation on this platform.

Quoted text here. Click to load it

And, x ::= y effectively says the same -- do you pronounce the colons?
Instead, use a verb that indicates the action being performed:
      x gets y

I learned to code with left-facing arrows instead of equal signs
to make the "assignment" more explicit.

Quoted text here. Click to load it

No, your *compiler* tells you that.  If you've NEVER glossed over
such an assignment in your code, you've ALWAYS had a compiler holding
your hand for you.  I'm glad I didn't have to wait 10 years for such
a luxury before *I* started using C.

Quoted text here. Click to load it

What you care about is:
- does it do what it is intended to do
- can others "skilled in the art" understand its intent

I'll frequently store pointers to functions where you might store
a variable that you conditionally examine (and then dispatch to
one of N places in your code).  In my case, I just invoke the
function THROUGH the pointer -- the tests were done when I *chose*
which pointer to stuff into that variable (why should I bother to
repeat them each time this code fragment is executed?)

When you do code reviews, do you all sit around with laptops and
live code copies?  Or, do you pour over LISTINGS with red pens?
Do you expect people to just give the code a cursory once-over?
Or, do you expect them to *read* the code and act as "human
compilers/processors"?

Quoted text here. Click to load it

There is no such thing as a perfect style.  You adopt a style that
works for you and measure its success by how buggy the code is (or
is not) that you produce and the time that it takes you to produce it.

I suspect if I sat you down with some of these early and one-of-a-kind
compilers, you'd spend a helluva lot more time chasing down bugs that
the compiler didn't hint at.  And, probably run the risk of some creeping
into your release (x=y=3) that you'd never caught.

Instead of pushing an update to the customer over the internet, you'd
send someone out to their site to install a new set of EPROMs.  Or,
have them mail the product back to you as their replacement arrived
(via USPS).  Kind of annoying for the customer when he's got your
device on his commercial fishing boat.  Or, has to lose a day's production
while it's removed from service, updated and then recertified.

Quoted text here. Click to load it

People are intimidated by pointers.  I should "break that habit" because
of their shortcomings?  Or because some standards committee decrees?
Despite the fact that I produce higher quality code for less money than
the adherents of those standards?

Quoted text here. Click to load it

The new programmer has to be aware of why things are the way they
are.  Or, fail to learn history's lessons.  What does he/she do
when faced with one of these tools?  Or, a build environment that
has turned off all warnings (does he even know that has happened)?

There's a reason you can look at preprocessor output and ASM
sources.  Because they are the only way to understand some nasty
bugs that may arise from your misunderstanding of what a tool
SHOULD be doing; *or*, from a defective tool!  (a broken tool
doesn't have to tell you that it's broken!)


Re: XC8 novice question
On 12/09/16 17:19, Don Y wrote:
Quoted text here. Click to load it

<snip for brevity>

Quoted text here. Click to load it

Parsed by who or what?  A compiler would parse it as "x = -1;".  I  
assume we are still talking about C (or C++) ?

When writing, I would include appropriate spaces so that it is easy to  
see what it means.

Quoted text here. Click to load it

That is a completely different statement.


Quoted text here. Click to load it

I am afraid I still don't get your point.  "x = -1;" is exactly how I  
would write it.  I believe spacing like that is good style, and helps  
make it clear to the reader and the writer how the statement is parsed.  
  And like in normal text, appropriate spacing makes things easier to read.

Quoted text here. Click to load it

I know.  But I prefer "p = &buffer[0];", because I think it looks  
clearer and makes more sense.  To my reading, "buffer" is an array - it  
does not make sense to assign an array to a pointer-to-int.  (I'm  
guessing at types here, since they were never declared - adjust them if  
necessary if "buffer" was an array of char or something else.)

C converts arrays or array operations into pointers and pointer  
operations in certain circumstances.  I wish it did not - but I can't  
change the language.  But just because the language allows you to write  
code in a particular way, and just because many people /do/ write code  
in a particular way, does not necessarily mean it is a good idea to do so.

Quoted text here. Click to load it

Again, I can only say - get a decent compiler, and learn how to use it  
properly.  If you cannot use good compiler (because no good compilers  
exist for your target, at least not in your budget), then use an  
additional static error checker.

To be used in a safe, reliable, maintainable, and understandable way,  
you need to limit the C features you use and the style you use.  (This  
applies to any programming language, but perhaps more to C than other  
languages.)  And you use whatever tools you can to help spot errors as  
early as possible.


Quoted text here. Click to load it

Again, spaces are your friend.

Quoted text here. Click to load it

Again, that's why you have to limit the features of C that you use.  And  
get whatever help you can from your tools to spot the errors (even if  
they are technically valid C).

Quoted text here. Click to load it

Bags don't "yield" apples.

Quoted text here. Click to load it

Many people do.  I don't.  I really do not think it helps in any way,  
and it gives unnecessary emphasis to a rather minor issue, detracting  
from the readability of the code.

But I am aware that some people think it is a useful idiom - and that a  
good many people think it is just something you do, because lots of  
other people do it.  I'm assuming you are in the first category here,  
and could give good reasons why you like all caps here, but I don't  
think we need to introduce any more points of disagreement and  
discussion at the moment!

Quoted text here. Click to load it

And again, you are missing the point.  I am not writing code for a 40  
year old compiler.  Nor is the OP.  For the most part, I don't need to  
write unpleasant code to deal with outdated tools.

I have, in the past, used far more limited compilers.  I have worked  
with compilers that only supported C90/ANSI, meaning I can't mix  
declarations and statements.  I have worked with compilers that have  
such god-awful code generation that I had to think about every little  
statement, and limit the number of local variables I used.  Very  
occasionally, I have to work on old projects that were made using such  
tools - and I have to go back to the dark ages for a while.

Perhaps, long ago when the tools I had were poor and the company I  
worked for did not have the budget for a linter, it might have made  
sense to write "if (CONSTANT == expression)".  But not now - and I don't  
think there will be many developers working today for which it would  
still make sense.

Quoted text here. Click to load it

Neither is clear enough.

Quoted text here. Click to load it

I don't pronounce colons.  I also don't use a programming language with  
a ::= operator.  But if I did want to pronounce it, then "x gets y"  
would be fine.

Quoted text here. Click to load it

I think that <- or := is a better choice of symbol for assignment.  The  
designers of C made a poor choice with "=".

Quoted text here. Click to load it

I have used warnings on such errors for as long as I have used compilers  
that conveniently warned about them.  But I can say it is very rare that  
a compiler /has/ warned about it - it is not a mistake I have made more  
than a couple of times.  Still, I want my tools to warn me if it were to  
happen.

Quoted text here. Click to load it

Those are certainly important - but they are not the only criteria in  
judging the best way to write a piece of code.

Quoted text here. Click to load it

I expect code to be as simple to understand as possible, so that it  
takes as little time or effort as possible for other people to read.  
That way others can spend their effort on confirming that what the code  
does is the right thing, rather than on figuring out what the code does  
first.

Quoted text here. Click to load it

Yes.


No.

Static checking by the compiler is not a substitute for writing correct  
code.  You make it sound like I program by throwing a bunch of random  
symbols at the compiler, then fixing each point it complains about.  The  
checking is automated confirmation that I am following the rules I use  
when coding, plus convenient checking of silly typos that anyone makes  
on occasion.


Quoted text here. Click to load it

I have mailed EPROMs to customers, or had products delivered back for  
program updates.  But never due to small mistakes of the sort we are  
discussing here.


Quoted text here. Click to load it

Break the habit if it was based on how you had to work with old tools,  
and the habit is not helpful with modern development.

Quoted text here. Click to load it

Again, you see to assume that I am recommending programming by luck -  
randomly writing "if (x = 1)" or "if (x == 1)" and relying on the tools  
to fix the mistakes.

The new programmer should learn to take advantage of new tools, and  
concentrate efforts on problems that are relevant rather than problems  
are no longer an issue (to the extent that they ever /were/ an issue).  
And if that new programmer is faced with poorer tools, then he or she  
will have to learn the idiosyncrasies at the time.  And the lack of  
warnings on "if (x = 1)" is unlikely to be the most important point.

Quoted text here. Click to load it

I have almost /never/ had occasion to look at pre-processor output.  But  
I do recommend that embedded programmers should be familiar enough with  
the assembly for their targets that they can look at and understand the  
assembly listing.



Site Timeline