Author Topic: Previously unknown 'C' behavior (to me).  (Read 18246 times)

0 Members and 1 Guest are viewing this topic.

Offline hamster_nzTopic starter

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Previously unknown 'C' behavior (to me).
« Reply #75 on: April 25, 2017, 10:07:38 pm »
I mean, if you do embedded programming, you'd expect:
Code: [Select]
    for (uint8_t count=1; count != 0; count++) {
       // Stuff
    }
to terminate after about 255 loops, right?   Not be optimized into an infinite loop because "integer overflow behavior is undefined and the optimizer decided that you'll never hit zero by incrementing an unsigned variable" ?   Ha hah!  Surprise!

Um, it does for me... (at least on GCC):
Code: [Select]
$ cat check3.c
#include <stdio.h>

int main(int argc, char *argv[])
{
    for (unsigned char count=1; count != 0; count++) {
      printf("x\n");
    }
}
$ ./check3| wc -l
255
$
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: Previously unknown 'C' behavior (to me).
« Reply #76 on: April 26, 2017, 12:56:03 am »
If the hardware masks off all but the lower 5 bits of the shift argument before applying it then even in assembly the results may not be what you hoped for.
Competent assembly language programmers know what the instructions do, and don't hope for results that are impossible.

 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19511
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Previously unknown 'C' behavior (to me).
« Reply #77 on: April 26, 2017, 07:14:35 am »
If the hardware masks off all but the lower 5 bits of the shift argument before applying it then even in assembly the results may not be what you hoped for.
Competent assembly language programmers know what the instructions do, and don't hope for results that are impossible.

Indeed. But they shouldn't have to. C is the only language I've used where I've found it beneficial to look at the compiler's output to see if it is doing what I intend.

Now I quite enjoy doing that, but that should only be necessary to see if the output hasn't been pessimised, not to check correctness.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4037
  • Country: nz
Re: Previously unknown 'C' behavior (to me).
« Reply #78 on: April 26, 2017, 01:20:54 pm »
If the hardware masks off all but the lower 5 bits of the shift argument before applying it then even in assembly the results may not be what you hoped for.
Competent assembly language programmers know what the instructions do, and don't hope for results that are impossible.

Indeed. But they shouldn't have to. C is the only language I've used where I've found it beneficial to look at the compiler's output to see if it is doing what I intend.

Now I quite enjoy doing that, but that should only be necessary to see if the output hasn't been pessimised, not to check correctness.

If the assembly language output is incorrect according to the C specification then submit a bug report to your compiler vendor.

If the assembly language output is correct according the C specification but  incorrect according to your notions of what your ideal language *should* do then I suggest you use a programming language more appropriate to your needs. Java or C# might be it. Or D. Or Go. Or a Lisp. Or Python. There are many many languages designed to provide safety and "mathematical" results.

C is a very sharp but incredibly useful knife. Skilled people should be allowed sharp knives if they want them and know how to use them safely.

Alas, many people who think they know, don't. And don't want to learn.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Previously unknown 'C' behavior (to me).
« Reply #79 on: April 26, 2017, 01:26:49 pm »
If the hardware masks off all but the lower 5 bits of the shift argument before applying it then even in assembly the results may not be what you hoped for.
Competent assembly language programmers know what the instructions do, and don't hope for results that are impossible.

Indeed. But they shouldn't have to. C is the only language I've used where I've found it beneficial to look at the compiler's output to see if it is doing what I intend.

Now I quite enjoy doing that, but that should only be necessary to see if the output hasn't been pessimised, not to check correctness.

Me too. I typically take a look at the compiler generated assembly output to see what is going on and how well I can express my intentions for the compiler. Nowadays compilers are pretty good at optimizing so it is also useful to see how the compilers performed the optimization.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19511
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Previously unknown 'C' behavior (to me).
« Reply #80 on: April 26, 2017, 01:43:41 pm »
If the assembly language output is correct according the C specification but  incorrect according to your notions of what your ideal language *should* do then I suggest you use a programming language more appropriate to your needs. Java or C# might be it. Or D. Or Go. Or a Lisp. Or Python. There are many many languages designed to provide safety and "mathematical" results.

Alas, many people who think they know, don't. And don't want to learn.

Quite. In this case it is that none of those languages provide safety, and none of them provide "mathematical" results.

I like tools that help me concentrate on my problems. I dislike tools that force me to concentrate on them rather than my problem.

I like draining swamps, not being up to my neck in alligators :)
« Last Edit: April 26, 2017, 06:41:26 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: Previously unknown 'C' behavior (to me).
« Reply #81 on: April 26, 2017, 05:40:36 pm »
Me too. I typically take a look at the compiler generated assembly output to see what is going on and how well I can express my intentions for the compiler. Nowadays compilers are pretty good at optimizing so it is also useful to see how the compilers performed the optimization.

I never do this. If I want to get particular assembly, I use assembler. It's sort of silly to tweak C code into generating the assembler output you want while you can do it better and faster without the C compiler.

If I decided to use C, I don't care about assembler.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19511
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Previously unknown 'C' behavior (to me).
« Reply #82 on: April 26, 2017, 06:40:43 pm »
Me too. I typically take a look at the compiler generated assembly output to see what is going on and how well I can express my intentions for the compiler. Nowadays compilers are pretty good at optimizing so it is also useful to see how the compilers performed the optimization.

I never do this. If I want to get particular assembly, I use assembler. It's sort of silly to tweak C code into generating the assembler output you want while you can do it better and faster without the C compiler.

If I decided to use C, I don't care about assembler.

That's a reasonable conceptual approach.

But it does bring the requirement for you to accurately inform the C compiler about what it can and can't presume about your assembler code, particularly w.r.t. optimisation. I don't know how the hell you can not only ensure but also assure that has been done adequately. N.B. assure != ensure, assure != insure, ensure != insure (although many nominally English speakers get the last wrong :( )
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: Previously unknown 'C' behavior (to me).
« Reply #83 on: April 26, 2017, 07:18:25 pm »
I've found it beneficial to look at the compiler's output to see if it is doing what I intend.

Now I quite enjoy doing that, but that should only be necessary to see if the output hasn't been pessimised, not to check correctness.
When I am programming in a high level language I 'think' in that language, so looking at the assembler output isn't very useful. If it isn't what I expect then either the source code is wrong (most likely), or the compiler is buggy (unlikely) or what I am trying to do isn't suited to that language. I have written a few PC programs in C and FreeBASIC, and wouldn't dream of looking at the machine code output. Just trying to understand it would be a nightmare, let alone determining if it was doing what I wanted! 

Quote from: NorthGuy
If I want to get particular assembly, I use assembler.
Same here. If I want efficiency I use assembler. If I just want to bang some code out with the least effort I use whatever language does it for me best. No point agonizing over how efficient your compiler is if it gets the job done.

Quote
It's sort of silly to tweak C code into generating the assembler output you want while you can do it better and faster without the C compiler.
It does seem a bit bit silly, however I can see the appeal of being able to do everything in the same language.   
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Previously unknown 'C' behavior (to me).
« Reply #84 on: April 26, 2017, 07:47:38 pm »
Me too. I typically take a look at the compiler generated assembly output to see what is going on and how well I can express my intentions for the compiler. Nowadays compilers are pretty good at optimizing so it is also useful to see how the compilers performed the optimization.

I never do this. If I want to get particular assembly, I use assembler. It's sort of silly to tweak C code into generating the assembler output you want while you can do it better and faster without the C compiler.

If I decided to use C, I don't care about assembler.

In the embedded systems in which the code size and RAM size are limited one typically needs to be very careful in how to write the code. Writing code for PC or Linux-based embedded system with lots of resources available, I do not really bother looking at the compiler output. When I really need to optimize the code for speed, I might take a look at the compiler output and try to figure out how the compiler will be able to create more optimized code.
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: Previously unknown 'C' behavior (to me).
« Reply #85 on: April 26, 2017, 08:18:08 pm »
I never do this. If I want to get particular assembly, I use assembler. It's sort of silly to tweak C code into generating the assembler output you want while you can do it better and faster without the C compiler.

If I decided to use C, I don't care about assembler.
I have done this but as part of an effort to reverse engineer code which I knew had been built with a particular compiler. I knew roughly what the C code would look like based on the assembler, then tweaked it until the output matched exactly.

I briefly became interested in whether the process could be used to build a decompiler but quickly realised that it was a non starter as it required too much wetware input to get to the first approximation.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19511
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Previously unknown 'C' behavior (to me).
« Reply #86 on: April 26, 2017, 09:24:35 pm »
I've found it beneficial to look at the compiler's output to see if it is doing what I intend.

Now I quite enjoy doing that, but that should only be necessary to see if the output hasn't been pessimised, not to check correctness.
When I am programming in a high level language I 'think' in that language, so looking at the assembler output isn't very useful. If it isn't what I expect then either the source code is wrong (most likely), or the compiler is buggy (unlikely) or what I am trying to do isn't suited to that language. I have written a few PC programs in C and FreeBASIC, and wouldn't dream of looking at the machine code output. Just trying to understand it would be a nightmare, let alone determining if it was doing what I wanted! 

Think of embedded systems where you need to be sure peripherals' registers have to be peeked/poked in very specific ways.

Think of embedded systems where you are cycle counting some parts of the code, and have to exclude unexpected code bloat in others.

Think of SMP systems where you have to ensure and assure multiprocessors, memory and caches interact correctly.

Think of the useful motto w.r.t both your tools and your understanding of them, "trust, but verify".
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline hamster_nzTopic starter

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Previously unknown 'C' behavior (to me).
« Reply #87 on: April 26, 2017, 09:51:57 pm »
I used to do a lot of looking at the compiler output, to see how I could influence the speed of code through styles used in the high level language.

However, if you do it for a while you get a feel for what does and what doesn't work, and you can look at code and go "well, that looks slow", "can I avoid this branch?", "how can I help this loop unroll", "if I align this data with that" and "I could speed this up by...", and you can get 50% the gain for 10% of the pain. I now only look at the generated code if I get something that is either spectacularly good or spectacularly bad.

Writing better performing code for me is now 80% of doing my job better (e.g. find a better way to do something),  19% of using the source to coerce the compiler to do a better job of code generation, and 1% of targeted optimization.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19511
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Previously unknown 'C' behavior (to me).
« Reply #88 on: April 27, 2017, 06:59:32 am »
A lot of "High Performance Computing" HPC codes are written in languages like C++, C, sometimes even JAVA or Python simply because the compilers are pretty good compared to manually written ASM, in the few cases where you have an extreme bottleneck that benefits highly from ultra optimization there are libraries for just those core performance primitives, and the rest of the program can stay portable and high level.

For those interested in HPC, have a look at http://people.ds.cam.ac.uk/nmm1/ Of particular relevance to this thread are the sections on what you have to do to avoid "surprises" with C/C++, and also the tenuous relationships between computer arithmetic and maths. It is not beginner material. It is based on personal experience since the 1960s.

Quote
It is a bit surprising that there aren't more "formal methods" used to express algorithms and data structures and state machines and so on though so that more such "boilerplate" patterns and program elements can actually be "provably correct" and also more easily analyzable with respect to side effects, execution time, dependencies, hazards, error cases, etc.  When you look at "design patterns" you see a lot of them implemented in high level languages but not so much integration of them into almost "atomic" memes / atoms of program construction so that you can sort of take the HLL out of the picture for those "elemental blocks / patterns" and then have a HLL that is more designed around working at the levels in between and above those pattern elements.

Yes and no.

"State space explosion" and the halting problem are "issues" for FSMs. In other cases the formal methods are more difficult than the code, and even if you do something useful there are two problems: ensuring correct mapping to a program, and interfacing with the non-formal stuff outside the proof.

As for design patterns, it is usually easier to throw something together, do a few unit tests to get a green light, ship the product and get customer service to deny there are intermittent problems :(

If you are interested in this topic, have a look at xC on the XMOS processors. It enables CSP/Occam style programming and interfacing with external devices on multicore processors, and the development environment will tell you exactly how fast each block will execute.

For example, there is hardware and language support to allow output to occur on a specific (500MHz) clock cycles, and waiting for inputs to change and recording the new value and clock cycle at which it occurred.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: evb149

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Previously unknown 'C' behavior (to me).
« Reply #89 on: April 27, 2017, 07:34:02 am »
Anyone  do anything interesting with code generation or domain specific languages or metaprogramming for embedded or otherwise?

I have through using Lisp-like language as an intelligent C macro preprocessor with hygienic macros and code generation. Simple code generation like iterators, linked list operations and simple code generation is something I would like to do. Unfortunately my Lisp in too weak for the task at the moment. Also, separating the preprocessor from the compiler makes it quite difficult to create a good code generator which would emit the code depending of the data types. In order to be able to extract the data types from the source code would require complex parser. The best option would be to integrate the preprocessors into the compiler as you could get the data type information from the compiler's parser.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19511
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Previously unknown 'C' behavior (to me).
« Reply #90 on: April 27, 2017, 08:04:10 am »
Anyone  do anything interesting with code generation or domain specific languages or metaprogramming for embedded or otherwise?

DSLs are superficially appealing, but they suffer from a number of disadvantages:
  • difficult to employ someone to use/maintain programs written in them; "5 years FrobDSL experience" on your CV counts for little
  • no tool support (e.g. browsing, syntax colouring, command completion) unless you write it yourself; vi and grep don't cut the mustard any more
  • they start out simple, but end up with cancerous growths that nobody understands; completely unlike C++, of course
A well-written library in a standard language has none of those problems.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: Previously unknown 'C' behavior (to me).
« Reply #91 on: April 27, 2017, 04:35:07 pm »
With a good and "familiar" optimizing compiler one doesn't have to write particularly "tight" C code to get tight machine language.  In fact one can rely very heavily on the compiler's optimizations and write extremely "simple" and "verbose" C code.  One just can take it for granted that the compiler will analyze the dependencies and flow and constant / variable parts of the data in a given block and optimize accordingly.

It is true that if you write bad code the compiler can improve it with optimizations. Actually, the worse is your code, the more the compiler can do. Opposite is also true: if your code is already good, the compiler cannot improve it as much.

However, the difference between good and bad code begins long before the first line is written. There's very important planning and thinking phase. As a result, a good code may contain completely different data structure and have a different flow. The good code usually comes up tight (there is less of it), simple (efforts spent to simplify it), verbose (easy to understand), and reliable (less room for bugs) at the same time. Bad code is likely to be bigger, overcomplicated, hard to understand and thereby buggy.

The compiler has to preserve the functionality as it is written. Therefore, there's absolutely no way a compiler can turn a bad code into a good one. This is a misconception.

 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26907
  • Country: nl
    • NCT Developments
Re: Previously unknown 'C' behavior (to me).
« Reply #92 on: April 27, 2017, 05:05:08 pm »
Anyone  do anything interesting with code generation or domain specific languages or metaprogramming for embedded or otherwise?

I have through using Lisp-like language as an intelligent C macro preprocessor with hygienic macros and code generation. Simple code generation like iterators, linked list operations and simple code generation is something I would like to do. Unfortunately my Lisp in too weak for the task at the moment.
I wouldn't go that route. Your projects will be completely unmaintainable because the next person needs to understand two languages AND how you split things in between. Besides that going this route shows a lack of understanding of the programming language and the inability to look for existing solutions. Throw in a bit of the 'not invented here' syndrom and the chaos is complete. If you want iterators, linked lists and so on then use a C/C++ library which offers those and rewrite the memory allocation back-end if you have to.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Previously unknown 'C' behavior (to me).
« Reply #93 on: April 28, 2017, 02:23:33 pm »
Anyone  do anything interesting with code generation or domain specific languages or metaprogramming for embedded or otherwise?

I have through using Lisp-like language as an intelligent C macro preprocessor with hygienic macros and code generation. Simple code generation like iterators, linked list operations and simple code generation is something I would like to do. Unfortunately my Lisp in too weak for the task at the moment.
I wouldn't go that route. Your projects will be completely unmaintainable because the next person needs to understand two languages AND how you split things in between. Besides that going this route shows a lack of understanding of the programming language and the inability to look for existing solutions. Throw in a bit of the 'not invented here' syndrom and the chaos is complete. If you want iterators, linked lists and so on then use a C/C++ library which offers those and rewrite the memory allocation back-end if you have to.

If you are using C macros, you are maintaining and creating chaos - and you are using an inferior macro language with poor capabilities and unhygienic macros.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf