I was told that the critical-safety development environment does not practically allow pointers to any functions. This is probably due to static code analysis.
What the heck is even "the critical-safety development environment"
If all the pointers are initialized at compile time, I don't think there would be any issues. Not to say it might not violate the rules some PHB declared.
From a practical perspective, why would one do anything other than initialize the table at compile time and declare it CONST? If you are really paranoid, keep a CONST copy of the table and reinitialize ii if the watchdog timer goes off.
If all the pointers are initialized at compile time, I don't think there would be any issues. Not to say it might not violate the rules some PHB declared.
From a practical perspective, why would one do anything other than initialize the table at compile time and declare it CONST? If you are really paranoid, keep a CONST copy of the table and reinitialize ii if the watchdog timer goes off.
For those CPUs executing code out of flash, the compiler will put the table in flash if it is declared CONST. That pretty much prevents the possibility of a pointer getting changed.
If it isn't automatically placed in flash, it is possible to force the linker to put it there anyway.
An excellent point and one of the many reasons I prefer C for most things. It's easy to understand the rules and what will actually happen.
Of course, for numerical work FORTRAN is better. Lex, yacc, awk and MATLAB/Octave all have their places too.
As merely one set of examples of how developers have been demonstrated to be confused, have a look at https://queue.acm.org/detail.cfm?id=3212479 and its references.
You ALWAYS have to trap the possibility of an invalid state
You ALWAYS have to trap the possibility of an invalid state
Why? Unless you calculate your states, which is relatively rare, you assign the values directly or draw them from some sort of table. In either case, the probability of getting an invalid state is slim to none.
There are many that go from FSM diagram or FSM text to executable C.
Going the other way would require that the C has been written in a sane manner (starting with no macros!) and probably using a specific set of design patterns. If you are expecting something to work well with arbitrary C (e.g. nested case statements!), then you are expecting to have solved several seriously intractable problems
As merely one set of examples of how developers have been demonstrated to be confused, have a look at https://queue.acm.org/detail.cfm?id=3212479 and its references.
Regarding that article I agree with the first comment "This is an excellent troll and strawman argument.".
For those who don't want to take the time to read it, here is a summary:
Old computers supported C.
Modern computers all support C.
Modern computers are complex.
Modern computers have issues.
Therefore continued support for C is the cause of everything that is wrong with computers today (incl Specter & Meltdown).
(Author must be one of those functional programming types)
I prefer switch/case for state machines. The compiler will generally implement with jump table. You ALWAYS have to trap the possibility of an invalid state so I generally find it cleaner than a function pointer table. The minute you need logic for an invalid value for your state value, you might as well use a case structure. There might be an esoteric method in C to trap invalid function pointers but I generally avoid the super elegant solutions.
You ALWAYS have to trap the possibility of an invalid state
Why? Unless you calculate your states, which is relatively rare, you assign the values directly or draw them from some sort of table. In either case, the probability of getting an invalid state is slim to none.
It is more than likely that somebody will code "state++;" to move onto the next state. Works fine until somebody else removes a state from the middle of a chain of states. Also, table driven state machines are quite common, at least in "programming 201" implementations.
One nice feature of using a state machines you can put the state variable into a buffer, so when debugging or looking at crash dumps you can see what states preceded the current one. Very handy.
OK, here's an example of the problem, from that article (read the article for the details)...
"According to the results of the survey, 36 percent were sure that they would be, and 29 percent didn't know. Depending on the compiler (and optimization level), it may or may not be. This is a fairly trivial example, yet a significant proportion of programmers either believe the wrong thing or are not sure."
That's an indication that C is part of the problem; I prefer tools that are part of the solution.
The question impiled by the article
You have a structure that is allowed (by the standard) to be padded to a convenient size for the compiler. You create an instance of that structure. You zero the structure. You then set some of the elements of the structure to non-zero values. Is the value of the padding now guaranteed to be zero? Yes / No / Don't know
OK, here's an example of the problem, from that article (read the article for the details)...
"According to the results of the survey, 36 percent were sure that they would be, and 29 percent didn't know. Depending on the compiler (and optimization level), it may or may not be. This is a fairly trivial example, yet a significant proportion of programmers either believe the wrong thing or are not sure."
That's an indication that C is part of the problem; I prefer tools that are part of the solution.No, it was trick question.QuoteThe question impiled by the article
You have a structure that is allowed (by the standard) to be padded to a convenient size for the compiler. You create an instance of that structure. You zero the structure. You then set some of the elements of the structure to non-zero values. Is the value of the padding now guaranteed to be zero? Yes / No / Don't know
No matter which answer you pick, you are wrong. Pick one and I'll prove the opposite to you (with code).
OK, here's an example of the problem, from that article (read the article for the details)...
"According to the results of the survey, 36 percent were sure that they would be, and 29 percent didn't know. Depending on the compiler (and optimization level), it may or may not be. This is a fairly trivial example, yet a significant proportion of programmers either believe the wrong thing or are not sure."
That's an indication that C is part of the problem; I prefer tools that are part of the solution.No, it was trick question.QuoteThe question impiled by the article
You have a structure that is allowed (by the standard) to be padded to a convenient size for the compiler. You create an instance of that structure. You zero the structure. You then set some of the elements of the structure to non-zero values. Is the value of the padding now guaranteed to be zero? Yes / No / Don't know
No matter which answer you pick, you are wrong. Pick one and I'll prove the opposite to you (with code).
That's very revealing because, if you think about it, what you claim to be able to do is simply impossible.
Hint: you might be able to make your point for one compiler with one target machine with one set of compiler flags - for one version of that compiler (because C compilers/linkers can and do change the code they emit).
int main(int argc, char *argv[])
{
struct padded s;
int i;
printf("'s' is %i bytes of memory\n", (int)sizeof(s));
/* Clear structure*/
memset(&s,0,sizeof(s));
/* Set some values */
s.a = 0xAA;
s.b = 0xBBBBBBBB;
printf("Byte dump:\n");
for(i = 0; i <sizeof(s); i++) {
printf("%02x ",((unsigned char *)&s)[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <memory.h>
struct padded {
unsigned char a;
unsigned int b;
};
int main(int argc, char *argv[])
{
struct padded s;
int i;
printf("'s' is %i bytes of memory\n", (int)sizeof(s));
/* Clear structure*/
s.a = 0;
s.b = 0;
/* Set some values */
s.a = 0xAA;
s.b = 0xBBBBBBBB;
printf("Byte dump:\n");
for(i = 0; i <sizeof(s); i++) {
printf("%02x ",((unsigned char *)&s)[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <memory.h>
struct padded {
unsigned char a;
unsigned int b;
};
int main(int argc, char *argv[])
{
struct padded s;
int i;
memset(&s,0xFF,sizeof(s));
printf("'s' is %i bytes of memory\n", (int)sizeof(s));
/* Clear every field in the structure*/
s.a = 0;
s.b = 0;
/* Set some values */
s.a = 0xAA;
s.b = 0xBBBBBBBB;
printf("Byte dump:\n");
for(i = 0; i <sizeof(s); i++) {
printf("%02x ",((unsigned char *)&s)[i]);
}
printf("\n");
return 0;
}
It seems that I may have been misinterpreting the "pointer to a function is a no-go" for years. I understand this that as long as the function pointer is const type, the world is safe.
QuoteThe question impiled by the article
You have a structure that is allowed (by the standard) to be padded to a convenient size for the compiler. You create an instance of that structure. You zero the structure. You then set some of the elements of the structure to non-zero values. Is the value of the padding now guaranteed to be zero? Yes / No / Don't know
No matter which answer you pick, you are wrong. Pick one and I'll prove the opposite to you (with code).
QuoteThe question impiled by the article
You have a structure that is allowed (by the standard) to be padded to a convenient size for the compiler. You create an instance of that structure. You zero the structure. You then set some of the elements of the structure to non-zero values. Is the value of the padding now guaranteed to be zero? Yes / No / Don't know
No matter which answer you pick, you are wrong. Pick one and I'll prove the opposite to you (with code).How is the padding (gaps between fields) of a structure changed by changing values inside the structure at runtime? Why should the padding length therefore become zero?
Accessing raw memory and disabling compiler checks might allow to write to the pad bytes (if the compiler included them at all) which are to be allocated by the memory management, but that would also not change the length of the padding, only it´s content.
An excellent point and one of the many reasons I prefer C for most things. It's easy to understand the rules and what will actually happen.
Er, no. Or at least only at a superficial level.
As merely one set of examples of how developers have been demonstrated to be confused, have a look at https://queue.acm.org/detail.cfm?id=3212479 and its references.Quote
Of course, for numerical work FORTRAN is better. Lex, yacc, awk and MATLAB/Octave all have their places too.
Er, yes
It is more than likely that somebody will code "state++;" to move onto the next state.
As merely one set of examples of how developers have been demonstrated to be confused, have a look at https://queue.acm.org/detail.cfm?id=3212479 and its references.
Regarding that article I agree with the first comment "This is an excellent troll and strawman argument.".
(...)