Hello experts, I'm a beginner of embedded system development.
I have question.about difference of two code.
at first, suppose there is function like
int SomeFunction(void) {
......
return (some integer);
}
And using this function return value like these
retval = SomeFunction();
if (retval == {some Variable}) {
. . .
....
former one doesn't make any problem, but when i used like latter one.. some times, retval is not correct and some strange value remains on r0 register...;
I don't know what is problem on latter one exactly...;
Could explain what is the problem of these?
Thank you very much for reading this..... though it is written by pool english...
As a general observation, the compiler can not eliminate a function call without ensuring that it implements all of the side-effects that calling that function at that specific time may have produced.
As a simple example, the following code compiled without access to the body of func_one() will produce code that calls func_one() twice:
extern int func_one(void); void example1(void) { func_one(); func_one(); }
This is the case even if func_one() has no side-effects simply because the compiler has no way of knowing this.
If, however, the body of func_one() is available, then its side-effects can be inlined and the calls subsequently optimised away, e.g.:
int func_one(void) { return 0; } void example2(void) { func_one(); func_one(); }
can compile such that example() makes no calls whatsoever, and just returns, i.e. the compiler can legitimately interpret this as:
void example2(void) { }
Conversely, if we replace func_one() with func_two() which does have side-effects, then even if it is inlined the effects must remain, e.g.:
int func_two(void) { return *(volatile int*)0xE000E010u; } void example3(void) { func_two(); func_two(); }
Could be implemented by the compiler as:
void example3(void) { *(volatile int*)0xE000E010u; *(volatile int*)0xE000E010u; }
which retains all of the side-effects, but could not be optimised to a single volatile access, or an empty function.
As such, there appears to be no requirement to need to be able to mark a function as volatile.
Beyond what is specified in the C standard, some tool chains do provide the opposite feature, i.e. the ability to tell the compiler that the function either has no side-effects and/or that its return value is dependent only on the arguments passed to the function and not on global variables / volatile memory accesses. Significant care must be taken, as these can potentially produce very strange results if used incorrectly, e.g:
extern int func_two(void) __attribute__((pure)); int example4(void) { return func_two() + func_two(); }
Might be expected to perform two separate reads of 0xE000E010, add them together and return the result, however, due to erroneously marking our previous func_two() as "pure", the compiler is free to implement this as:
int example4(void) { return func_two() * 2; }
i.e., reuse the value from the first call/read, and simply multiply it be two.
Simon.
I just... admire your knowledge simon...
Relly Rellay Thanks!!!!!