I mean, if you do embedded programming, you'd expect:Code: [Select]for (uint8_t count=1; count != 0; count++) {
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!
// Stuff
}
$ 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
$
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.
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.
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 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 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.
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.
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.
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 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.
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.
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'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!
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.
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.
Anyone do anything interesting with code generation or domain specific languages or metaprogramming for embedded or otherwise?
Anyone do anything interesting with code generation or domain specific languages or metaprogramming for embedded or otherwise?
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.
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.
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.