code optimiation

Given the cavalier attitude to robustness you've consistently expressed here, I find it hard to give this statement much credibility. I consider it much more likely you just didn't look closely enough to see the portability problems in your code.

Reply to
Hans-Bernhard Bröker
Loading thread data ...

Tim:

I've been programming in C as a hobby for about 6 years. As I program out of hobby, I have the freedom to program however I want. I took an interest in portable programming from early on.

Hans-Bernhard:

If there's a portability problem in a piece of code, I'll know about it. You'd be suprised how easy it is to stay fully-portable once you know the restrictions and freedoms of the C Standard. Here are some of the more "wild" freedoms that you have to keep an eye out for:

  • Integer types may contain padding bits, and so sizeof(type) * CHAR_BIT won't necessarily give you the amount of bits in a integer type.
  • The null pointer constant need not be all-bits-zero, thus using memset(p,0,sizeof p) to set it has undefined behaviour according to the Standard. Same goes for float and double.
  • Types smaller than int always promote to signed int, unless you're dealing with an small unsigned type whose greatest value is greater than INT_MAX, in which case it promotes to unsigned int.

You could always post a piece of non-portable code and see if I can cop what's wrong with it, that's if really want me to look like a fool. Portable programming is quite easy once you give it attention; I've written quite a few fully-portable programs. The Connect4 game I wrote for my microcontroller will work perfectly on a PC.

Reply to
Tomás Ó hÉilidhe

In message , Tomás Ó hÉilidhe writes

Portable across how many platforms?

You said:- I'd advocate using types like "uint_fast8_t" instead of "unsigned int"; that way you'll get good performance out of all kinds of machine, whether they be 8-Bit, 16-Bit or 5-billion-Bit.

Only if types like uint_fast8_t are implemented.

Which standard? No, it's not a trick question.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

On the contrary, that's exactly what it gives you: the amount of bits in the type. That's not the same as the amount of bits in the value. That's what you get for.

That set aside, I wonder how someone with this level attention to detail in one field, could be so recklessly resistent to advice in others.

Reply to
Hans-Bernhard Bröker

Quite a lot of the posters on here have been programming in various forms of C and more platforms, with or without operating systems on the target than you will have seen, for longer than you have been ALIVE!

Many understand the issues of portability and what CAN and what CANNOT be portable in an application.

Define 'portable', that is NOT a trick question.

.....

So your PC and the microcontroller have the same operating system and I/O interfaces then.

Only PART of your code is portable, the WHOLE application is not!

--
Paul Carpenter          | paul@pcserviceselectronics.co.uk
    PC Services
 Timing Diagram Font
  GNU H8 - compiler & Renesas H8/H8S/H8 Tiny
 For those web sites you hate
Reply to
Paul Carpenter

The C Standard calls them "value representational bits".

Strangely enough, limits.h doesn't tell you how many value- representational bits there are in the various types (except for "char"). Using constants such as UINT_MAX, ULONG_MAX, though, you can narrow it down. There is, however, a clever macro called IMAX_BITS which can be used to determine the quantity value-representational bits in any integer type on any system.

I'm taking people's advice on board here, and I'm redesigning my circuit. I've even been making up small circuits on my bread board and using an ammeter to measure the current going through the LED's. The next incarnation of my Connect4 board will have plenty of 250 ohm resistors. :-D

Reply to
Tomás Ó hÉilidhe

Every platform for which there is a C compiler which abides by the C Standard. In order to do this, I have to:

1) Not invoke behaviour which is deemed to be "undefined" by the Standard. (e.g. the overflow of signed integer types, the subtraction of pointers that point to different objects) 2) Not rely on implementation-defined behaviour (e.g. integer promotion, the assumption of no padding in structs, assuming a function pointer will fit in a void*).

They're declared as typdef's in stdint.h.

C89 doesn't include stdint.h, but C99 does. There's many compliant C89 compilers, but very few compilers that are fully-compliant to C99. I think all compilers nowadays have a stdint.h though. And for the few that don't, you can always write a little one yourself, for example here'd be one appropriate for the PIC16F684:

typedef char unsigned uint_fast8_t; typedef unsigned uint_fast16_t; typedef long unsigned uint_fast32_t;

The C89 standard. Nowadays, even if compiler doesn't market itself as a C99 compiler, it will still tend to implement some of the more beneficial features of the C99 standard, such as:

  • stdint.h
  • compound literals (e.g. being able to write (int[2])(5,6) as an R- value)
  • the "inline" keyword for functions

C89 is still the dominant standard though.

Reply to
Tomás Ó hÉilidhe

That's not strange at all. There's no point in knowing that, so there's no need for to contain that knowledge.

Reply to
Hans-Bernhard Bröker

Chris H schrieb:

Oh well, yes. It's written from the perspective of the CPUs I have to deal with at work. That's mostly ARM and DSP. Also MIPS-variants, SH4 and so on.

E.g. CPUs that have roughly the number-crunching power as a 8 year old PC. All these had cache so far. Sometimes just 4k, sometimes a bit more..

In my experience on such CPUs memory bandwidth is the limiting factor unless the code is unoptimized beyond hope.

Cheers, Nils

Reply to
Nils

They your code will not run on all C compilers and is likely to be hopelessly inefficient.

Then you are wrong.

The ANSI standard? Not the ISO C95?

"It will tend" you have made many assumptions.

Not since 1990.....

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

Ever seen an exponential curve? The gaining of expertise is an exponential curve, whether it be driving a car, playing the guitar, programming in C.

While it's safe to assume that someone who has been programming for one month is better than someone who has been programming for one week, it is _not_ safe to assume that someone who has been programming for 20 years is better than someone who has been programming for 6 years. Why? Because you're so far along that exponential curve that time has become negligible and it's more a case of personal potential and aptitiude.

Just as an example, I've been playing the guitar for 11 years now but I've seen people who've been playing for 3 years that are better than me. Ever since I'd been playing for about two years or so, the gains I've made have become less and less. In fact I'd even hazard a guess that I played better guitar 9 years ago because I practised a hell of a lot more.

I know C, I know it very well. I know what's portable and I know what's portable. I have 6 years experience of programming in C, but leaving that aside, forgetting that I've any experience, I still would only have to read the C Standard to see whether a particular action results in well-defined behaviour, implementation-defined behaviour, or undefined behaviour. That is ALL there is to it, simple as.

see

Well in terms of programming in abidance to the C89 standard, I would say portability is:

"The code will function exactly as intended on every conceivable implementation of the C89 standard."

Obviously if you're using an entirely different interface (e.g. a computer monitor and keyboard instead of LED's and push buttons), then you're going to have either:

1) A simulator on the PC that will pretend you're using pins 2) A different source file for the PC and the microcontroller when it comes to input and output.

In my Connect4 program for example, the IO constitutes a small part of the program. The actual logic of the game is fully-portable: You can run it on everything from a micrcontroller to PC.

Reply to
Tomás Ó hÉilidhe

Never mind the portability. What about efficiency? Code that will run well on a 32bit system is not likely to run well on an 8 bit system. You would have to re-write it to work well with the smaller system.

The poster is being very over simplistic I think. Also pure ISO C will not be completely portable across 8-32 bit systems (efficiently if at all) without a lot of thought

Some systems eg 8 bit will use char rather than int for everything that can fit in a char. 16-31 bit systems default to char.

Whilst it is true that C is portable it is effectively a high level assembler.

I can supply commercial C source code for many things (RTOS, Stacks file systems etc) whilst the API's are all constant much of the source is dependant on the target MCU and the compiler used. The underlying HW is different, the size and number of registers is different so the way things are done is different.

It is not as simple as only using the well defined parts of C. Anyone who things that is all you need to do does not really grasp the problem.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

I've used that information several times, as have other C programmers, hence the need for the IMAX_BITS macro which provides us with a compile time constant that can even be used for the length of an array, e.g.:

char array[16]; /* Hardcoded 16 for the amount of bits in an int */

char array[IMAX_BITS( (unsigned)-1 )]; /* Magically get the figure for us */

Just as an aside, what IMAX_BITS actually does is it takes a number where there's an uninterrupted sequence of one's, .e.g:

00000000111111111111111111111111

and then tells you how many one's there are set in it. By giving it "(unsigned)-1", you're passing it the maximum value for an unsigned int.

Reply to
Tomás Ó hÉilidhe

Elaborate on that. I know you're wrong, but I'd still like to see what you think you're right.

Give me an example of a compiler that doesn't have an stdint.h. I know PIC C doesn't, but that's the only one I'm aware of.

For every one you mention that doesn't have stdint.h, I can give you several examples of the contrary.

Not the 1989 standard, also known as the 1990 standard. That's actually no difference between them other than editorial stuff, e.g. re-ordering of the index at the start.

You blindly assume that I exploit these C99 features when writing C89 code. I don't.

Nope, still 1989.

Reply to
Tomás Ó hÉilidhe

Again with the blind, sweeping statements. I find it incredibly easy to accomodate both microcontrollers and PC's when writing fully- portable code.

It's been done. There are some quirks when it comes to some microcontroller compilers, e.g. the placement of auto variables on a stack, but good microcontroller compilers have a small finite list of ways in which the flout the Standard.

Reply to
Tomás Ó hÉilidhe

With stupidity like that I am not going to continue.

Then I suspect you are working with a limited knowledge.

I am sure you could but if only 1 doesn't have it your code is not portable.

No it's not

You don't understand.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

In message , Tomás Ó hÉilidhe writes

Not by a long way.... you have much to learn.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

[snip]

Many of the "bigger" processors (68K family, ARM, etc.) do have such a capability. The compiler has to support the operation regardless of how it does it, so use of the auto-increment/decrement construct at the source level shouldn't be a liability.

It took me quite awhile to realize that it even produced the desired result...

[snip]
Reply to
Everett M. Greene

Having read the threads you are currently in on this NG I can only conclude you are a self deluded idiot.

What do you do for a full time job?

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

My experience with multi-platform development is one can claim something is portable across *certain* targets only after one has build for each individual target, tested it on those targets and confirmed that it does behave as specified on those targets. Claiming that something is *fully* portable would imply you would have done all that for any conceivable platform with any conceivable compiler.

Sticking to the constructs that are the well-defined in the standard is a good start for making things portable, but is by no means sufficient to be able to claim that your code is *fully* portable. Even if you limit your claim to compilers that claim to be fully compliant with the standard you may still encounter corner cases were different compilers do yield different behavior. Sometimes because the compiler knowingly or unknowingly deviates from the standard, or because of ambiguities in the standard.

Reply to
Dombo

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.