XC8 novice question

If you learn anything from this thread, it should be that you never use "char" for numbers. Use "uint8_t" or "int8_t" depending on whether you want unsigned or signed types. This is /critical/ to writing good embedded software, especially on 8-bit devices.

Reply to
David Brown
Loading thread data ...

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)

Reply to
Don Y

I've picked up quite a bit from this thread - as you can probably guess! I'll revisit my code and reassess the data types for all my variables.

Thanks David.

Reply to
rwood

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 
www.videosolutions.ltd.uk
Reply to
Mike Perkins

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.)

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.

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.

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

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.

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.

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.

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;

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.

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.

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".

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

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.

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

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.

Reply to
David Brown

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.

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.

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

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

  1. They have code reviews to help spot errors.

  2. They have comprehensive testing.

  1. They do not write code that reads backwards.

  2. 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.

Reply to
David Brown

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.

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

As above.

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

Of course.

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

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

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 
www.videosolutions.ltd.uk
Reply to
Mike Perkins

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

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

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())) ...

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

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.

Reply to
David Brown

tto:

not always, it depends on the compiler.

Bye Jack

Reply to
Jack

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

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;

You'll more frequently encounter: p = buffer;

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!

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;

If the bag yields 3 apples...

I ALWAYS use caps for manifest constants.

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!

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.

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.

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.

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"?

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.

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?

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!)

Reply to
Don Y

It's a known issue with the compiler. The support team has logged it, so it may get fixed at some point. If you Google the warning, you will find many threads discussing the issue on the Microchip support forum.

Reply to
John Temples

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.

Reply to
David Brown

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

--
Les Cargill
Reply to
Les Cargill

Am 11.09.2016 um 15:14 schrieb snipped-for-privacy@downunder.com:

It really wasn't, because as a solution it was incoherent, incomplete, and insular. Anyway, there really weren't that many years between C90 and UCS2.

8-bit unsigned char for non-ASCII characters created more problems than it ever solved. Instead of having one obvious, while painful restriction, we now had *) dozens of conflicting interpretations of the same 256 values, *) no standard way of knowing which of those applied to given input *) almost no way of combining multiple such streams internally *) no useful way of outputting a combined stream

Not quite. You need a type with _at_least_ 21 bits. It doesn't have to be a 21-bit data type.

The problem: yes. But essentially nobody dared to implement an actual solution.

C itself has had some support for wider character representations and all that from the get-go (i.e. the first actual standard in 1990), but I don't think I've ever seen anyone use that in anger.

But they could generally only display Latin, Cyrillic, _or_ Arabic, but not all of them on the same screen. I.e. they suffered from the same problem as using 8-bit unsigned for 'char' does: one more bit just isn't enough to do the job.

Reply to
Hans-Bernhard Bröker

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.

That is a completely different statement.

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.

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.

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.

Again, spaces are your friend.

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).

Bags don't "yield" apples.

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!

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.

Neither is clear enough.

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.

I think that

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.

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

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.

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.

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.

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.

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.

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.

Reply to
David Brown

What he is getting at is that in the original K&R C the compound assignment operator was of the form =op. It was later changed to the current op= because of the ambiguity he noted. See the K&R section of

formatting link

I remember having to change a bunch of code for the "new" compilers.

Reply to
Dennis

In Standard C it is. _Very_ early in the development of the language the syntax had a loophole that caused some compilers to parse "x =- 1;" as if one had written "x -= 1;"

That's water 30+ years under the bridge, though. Even Lint has given up warning about this particular idiom long ago.

Reply to
Hans-Bernhard Bröker

No. Dig out a copy of Whitesmith's or pcc. What is NOW expressed as "x -= 1" was originally expressed as "x =- 1". Ditto for =+, =%, etc. So, if you were a lazy typist and liked omitting whitespace by thinking it redundant, you typed: x=-1; and got: x=x-1; instead of: x = (-1);

My point is that most folks would think x=-1 (or x=+2, etc.) bound the sign to the value more tightly than to the assignment operator.

The same sort of reasoning applies to x=y/*p; where the '*' ends up binding more tightly to the '/' to produce the comment introducer, "/*". Note that the problem persists in the language's current form -- but compilers often warn about it (e.g., detecting "nested" comments, etc.)

No. It is what the statement above HAS BECOME! (as the language evolved)

See above.

Or, better yet, google turns up:

Perhaps an interesting read for folks didn't have to write code "back then".

I prefer it because I am more hardware oriented. I think of "objects" (poor choice of words) residing AT memory addresses. So, it is only natural for me to think about "the address of the zeroth element of the array".

For how many different processors have you coded? I have compilers for processors that never made it into "mass production". And, for processors that saw very limited/targeted support. If I'm willing to FUND the development of a compiler -- knowing that I may be the only customer for that compiler -- then I can "buy" all sorts of capabilities in that compiler!

OTOH, if I have to pass those costs along to a client, he may be far less excited about how "good the tool is" and, instead, wonder why *I* can't compensate for the tool's quality.

What were tools like 20 years ago? Could you approach your client/employer and make the case for investing in the development of a compiler with

2016 capabilities? Running, *effectively*, on 1995 hardware and OS? Or, would you, instead, argue that the project should be deferred until the tools were more capable?

Or, would you develop work styles that allowed you to produce reliable products with the tools at your disposal??

Spaces (or parens) are a stylistic choice. The language doesn't mandate their use. E.g., this is perfectly valid: y=/*I want to initialize two variables to the same value in a single stmt*/x=3;

It's a bad coding STYLE but nothing that the compiler SHOULD complain about!

Sure they do! Do you think they HORDE apples?

Would you write: const zero = 0; const nine = 9; for (index = zero; index < nine; index++)... Or: const start = zero; const end = nine; for (index = start; index < end; index++)... Or: for (index = START; index < END; index++)...

The latter makes it abundantly clear to me (without having to chase down the declaration/definition of "start", "end", "zero" or "nine". (who is to say whether "zero" actually maps to '0' vs. "273" -- 0 degrees K!)

No, YOU are missing the point! I'm writing code with 40 years of "respectible track record". You're arguing that I should "fix" something (i.e., my style preferences) that isn't broken. Because it differs from what your *20* year track record has found to be acceptable. Should we both wait and see what next year's crop of developers comes up with? Maybe Hungarian notation will be supplanted by Vietnamese notation? Or, we'll decide that using identifiers expressed in Esperanto is far more universally readable?

I can then argue that we shouldn't bother with such an archaic language, at all! Look at all the cruft it brings along with it! Why not wait to see what pops up tomorrow as the language (and development style) du jour? Or, why risk being early adopters -- let's wait a few *weeks* before adopting tomorrow's advances!

Programming is still an art, not a science. You rely on techniques that have given you success in the past. When 25% of product returns are due to "I couldn't figure out how to USE this PoS!", that suggests current development styles are probably "lacking".

So, what's your solution?

Then you come up with alternative ways of conveying the information present in that symbology.

E.g., "::=" (used to initialize a variable) vs '=' (used to define

*constants*, but not variables, and test for value equality) vs ":=:" (to test for address equality) vs ":=" (chained assignment) in Algol; '=' vs "==" in C; ":=" vs. '=' and ':' and "==" in Limbo; etc.

When conversing with someone not fluent in a language, the actual punctuation plays an important role. Saying "x gets y" to someone who isn't familiar with Algol's "::=" would PROBABLY find them writing "x = y". When "reading" Limbo code to someone, I resort to "colon-equals", "equals" and "colon" so I'm sure they know exactly what I'm saying (because the differences are consequential)

I want my tools to warn me of everything that they are capable of detecting. INCLUDING the tool that occupies my cranial cavity!

What's simple to me might not be simple to you! E.g., I naturally think in terms of pointers. Others prefer array indexes. For me to jump/call *through* a pointer is far more obvious than encoding some meaning into a flag at some point in the program. Then, decoding that flag at another point and dispatching based on that decode! The latter requires keeping two pieces of code in sync (encode & decode). The former puts everything in one place (encoding).

Should I write code at a level that a newbie developer can understand? Should I limit myself to how expressive and productive I can be out of fear that someone might not be quick to grasp what I've written?

Where am I writing "INcorrect code"? It meets the specifications of the language. It compiles without errors or warnings. It fulfills the goals of the specification.

It's just that *you* don't like my style! Is that what makes it "not correct"? If I replaced the identifiers for manifest constants with lowercase symbols, would that make it MORE correct? Should I use camelcase identifiers? Hungarian notation? Embedded underscores? How do any of these make the code more or less "correct"?

I've *never* had to update a product after delivery. Because the cost of doing so would easily exceed the profit margin in the product!

I've had clients request modifications to a product; or tweeks for specific customers. But, those aren't "bug fixes", they're effectively "new products" that leverage existing hardware.

I did some work for a firm in Chicago. Big company with lots of bean counters. So, they could tell you what everything "costs" (them!). I had proposed "swapping ROMs" as an upgrade path for the product. They told me that it costs them $600 to send someone into the city to TOUCH an installed device:

- gotta schedule the visit (can't just walk in unannounced and hope your customer will be eager to greet you AND have the equipment "out of service" at that time)

- gotta drive into the city, find a place to park the car, lug your test equipment (have to prove to the customer that what you're doing DOES work) and documentation/paperwork/workorder to the customer's facility

- gotta spend some time actually making the upgrade, testing it and reassuring the customer that it actually works

- gotta schlep all your stuff back to the car, pay the parking fee

- drive back to work and check the vehicle back in

- fill out the trip report and any expense report

- gotta pay the employee for this time (plus his share of "burden")

- gotta make sure you have enough employees with this sort of training on hand at all times (cuz you can't simply decide not to handle upgrades because Bob quit!)

$600. And that was more than 30 years ago! For a product that *cost* $300 (DM+DL) to build!

"No, there will be no upgrades. You will get it right the first time!"

Who is to say it is not helpful? Has the quality of my work suffered? Am I suddenly writing buggier code?

If it isn't broke, don't fix it!

No. I'm acknowledging that people make mistakes, keyboards don't always "type" what you've told them to type, etc. I am *very* consistent in my design styles (hardware and software). If I look at something that I created and it doesn't strictly conform to "how I do things", I am instantly on alert: "Why is this not as it SHOULD be?" And, I start searching for an explanation in the accompanying commentary -- lest I be tempted to "fix" it (which will introduce a problem and explains why it WASN'T "as it should be" to begin with!)

Without the warning, the developer is likely to waste a boatload of time "seeing what he wants to see" and not what the *compiler* sees.

You've probably never "abused" the preprocessor in creative ways! :>

Reply to
Don Y

OK, thanks.

I came across K&R briefly C at university, but ANSI C was already the norm by the time I was actually doing anything with it. And I have no knowledge of C from before the first version of "The C Programming Language", and have not seen the syntax "x =- 1;" before.

History like this is interesting, but irrelevant to the issue of how to write code /today/.

Reply to
David Brown

Exactly the same problems existed with the 7 bit ISO646 from the

1960/70's.

In ISO 646 some of the US-ASCII code points were replaced by a national character, such as @ [ \ ] { | } _ ^ ~ $ #

The replacement characters were typically different for each country or at least each language. Try to combine texts from different languages produced a mess. This was a problem especially in countries with multiple official languages. Also writing names of foreign origin caused problems.

Think about Pascal or C-programming, with missing [ \ ] { | } ^

This was especially problematic for printing with a language specific printer (e.g. daisy chain) giving quite different looking printouts depending on which printer was used.

For programming, the most convenient way was to switch the terminal to US-ASCII, but unfortunately the keyboard layout also changed.

Digraphs and trigraphs partially solved this problem but was ugly.

With the introduction of the 8 bit ISO Latin, a large number of languages and programming could be handled with that single code page, greatly simplifying data exchange in Europe, Americas, Africa and Australia.

Reply to
upsidedown

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.