Storing local variable - variables

I want to ask a question which is confusing to me ,
when I write int x = 0 ; which is a local variable
I know it will be stored in the stack by using stack pointer , but how computer remember that this variable x is stored to this address ?
is that a compiler role or linker role or what happen exactly .

Related

Saving a memory address in a variable

1. If I initialize a variable 'a' (in the SRAM), can it happen that its location/position in memory changes each time I simulate or add other variables to the program? Or will it always remain in that location? (if I don't change it manually of course)
2. I would like to find out whether it's possible to save within a variable 'a' the memory address in which another variable 'b' is stored. Which function can I use?
Thanks!
(I am working on STM32CubeIDE)

can't edit integer with .noinit attribute on STM32L476 with custom linker file

I'm doing my first attempt working with linker files. In the end i want to have a variable that keeps it's value after reset. I'm working with an STM32L476.
To achieve this i modified the Linker files: STM32L476JGYX_FLASH.ld and STM32L476JGYX_RAM.ld to include a partition called NOINT.
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K -0x100
NOINIT (rwx) : ORIGIN = 0x8000000 + 1024K - 0x100, LENGTH = 0x100
}
/* Sections */
SECTIONS
{
...
/* Global data not cleared after reset. */
.noinit (NOLOAD): {
KEEP(*(*.noinit*))
} > NOINIT
...
In the main.c i initialize the variable reset_count as a global variable.
__attribute__((section(".noinit"))) volatile uint32_t reset_count = 0;
The =0 part is just for simplification. I actually want to set reset_count to zero somewhere in a function.
When i run the program and step through the initialization i would expect to see the value of reset_count as 0. But somehow i always get 0xFFFFFFFF. It seems like i can't edit the reset_count variable. Can anybody tell me how i can make this variable editable?
It is not clear from the question whether you want to have a variable that keeps its value when power is removed, or just while power stays on but hardware reset is pulsed.
If you want something that keeps its value when power is removed, then your linker script is ok to put the block in flash memory, but you need to use the functions HAL_FLASH_Program etc. to write to it, you can't just make an assignment. In addition, you could simplify the linker script by instead of creating the NOINIT output region, just putting >FLASH.
If you want a variable that just persists across reset wile power stays up then you need to put the variable into SRAM not FLASH, for example like this:
.noinit (NOLOAD) :
{
*(.noinit*)
}
> RAM2
Note that you don't need to use KEEP unless you want to link a section that is unreferenced, which will not be the case if you actually use the variables, and you don't need another * immediately before .noinit unless you section names don't start with a ., which they should.
You will not be able to write to the flash memory as simply as that. If you use ST HAL, there is a flash module that provides HAL_FLASH_Program() function.
Alternatively, if the data you are trying to store is 128 bytes or less and you have an RTC backup battery, you can use the RTC backup registers (RTC_BKPxR) to store your data.

MQL4 "undeclared identifier" - how can I fix this issue?

I'm currently trying to learn a programming language called MQL4, which is used to write trading algorithms. It is very closely based on C++/C/C#, so anyone with knowledge of these languages should be able to help me out with this one.
I'm trying to create a very simple program which tells me the length of the upper and lower shadows (wicks) of the last periods candlestick. To do this, I've tried using the following code:
double bod1 = Close[1] - Open[1];
double absbod1 = MathAbs( bod1 );
if( bod1 >= 0 )
{
double uwick1 = High[1] - Close[1];
double lwick1 = Open[1] - Low[ 1];
}
else
{
double uwick1 = High[ 1] - Open[1];
double lwick1 = Close[1] - Low[ 1];
}
Alert( "Lower Wick: " , lwick1 , " Upper Wick: " , uwick1 );
Q1: Why does this give the following error message?
Q2: Can you not define variables within an if(){...} statement?
Q3: If not, how can I define a variable which depends on some other factor?
I mean, suppose that I wanted to define the variable var such that var = a OR var = b depending on whether a > b or not.
Q4: How would I do this, if not by using if(){...} statements, as shown above?
If that language is similar to c++ then you should define your variable before if block, ex:
double uwick1 = 0;
if(bod1 >=0)
{
uwick1 = High[1]-Close[1];
In languages similar to C++, a variable defined in a block only exists inside that block.
So in your code:
double bod1 = Close[1]-Open[1];
double absbod1 = MathAbs(bod1);
if(bod1 >=0)
{
double uwick1 = High[1]-Close[1];
double lwick1 = Open[1]-Low[1];
}
else
{
double uwick1 = High[1]-Open[1];
double lwick1 = Close[1]-Low[1];
}
Alert("Lower Wick: " , lwick1 , " Upper Wick: " , uwick1);
A uwick1 variable is defined in the if block and then goes out of scope. Another uwick1 variable is defined in the else block and then goes out of scope. Finally, the Alert call references a uwick1 variable, but there aren't any variables in scope with that name.
If you define the variables before the conditional:
double bod1 = Close[1]-Open[1];
double absbod1 = MathAbs(bod1);
double uwick1;
double lwick1;
if(bod1 >=0)
{
uwick1 = High[1]-Close[1];
lwick1 = Open[1]-Low[1];
}
else
{
uwick1 = High[1]-Open[1];
lwick1 = Close[1]-Low[1];
}
Alert("Lower Wick: " , lwick1 , " Upper Wick: " , uwick1);
This code should work the way you expected.
WhileMQL4 may look like a C-language,beware it is not ( +it has a pair of compilation-modesthat have VERY DIFFERENT code-execution of the SAME SOURCE CODE... so Devil is hidden in details)
Your inital notes about similarity can and will cause a lot of troubles down the road.
Forget about C.
An anxient Assembler directive is worth repeating #ASSUME NOTHING
string is not a string, but a special case of struct and the list of differences grows.
MQL4 simply is not a C-language.
The sooner one realises, the better.
First,the language's execution model is subordinated in three, very different models:- in the MQL4 Script -- disconnected from asynchronous external FxMarketEventSTREAM- in the MQL4 Expert Advisor -- a code-execution is edge-triggered by FxMarketEventSTREAM- in the MQL4 Custom Indicator -- a code-execution is (sub)-batch-run once edge-triggered by FxMarketEventSTREAM
This is something none of the C-language has built-in.
Second,the language syntax evolves ( better to say, it creeps ) and new constraints start to apply. The only method how to cope with this is to re-read MQL4 Documentation literally on each and every update, yes, on each and every update. One may avoid unwanted surprises by this step ( still more suprises remain to become visible after compilation -- needles to say, that some parts of provided documentation is clearly wrong, some remain clear, until you compile the "compliant"-code and it gets rejected by compiler/parser. The worst comes on cases, that magically "pass"-through the compiler/parser phase and remain causing you nightmares on runtime, where the crippled code does strange things, that still passed all compilation/execution restrictions, but produce havoc ( sure, another story, but posted for complete warning about the MQL4-ecosystem risks and danger-zones -- so forget about C-language, your cruelest enemy is inside MetaQuotes Language revisions ( New-MQL4.56789... ) evolution )
New-MQL4.56789has introduced dual-compilation mode -- a #strict and an "old"
One of the "New" changes ( that has caused a cost of a few man*years of code-base re-design ) is a limited variable scope. Besides a dual globally-scoped variable construct, the "New"-MQL4.56789 started to "frame" a visibility of a declared variable so that "outside" the "outer" constructor of such variable, the symbol ceases to exist and is thus undefined, as your compile-time error reports.
Q1: is solved, the if(){...}else{...} were the limits for both pair of declarations ( bracketed parts {...} were the two, adjacent scopes, where doubles were defined & "visible" ) and your original code, outside of the {...}-zone tried to reference a symbol, that was not "known" outside the declaration-scope, so the compiler had to report that as "- undefined identifier" as it had no clue what the identifier should stand for.
Q2: Yes, one can define variables within an if(){...} statement. Such variables remain defined "inside" the scope of theirs {...}-outer-block. One may benefit from another architecture feature -- a declaration modifier static. This will maintain a code-execution-time persistency of a value of such defined variable during the whole lifecycle of the code runtime environment and whenever a code-execution path re-enters the variable's {...}-visibility scope, it's value ) upon each re-entry remains re-stored for re-use.
Q3+Q4: Declaring a variable is a principally important step and assigment of a value is another one. Having said this, one may observe problems once trying to declare+assign values in one single step. There a dependency may create problems for compiler -- in some previous MQL4-Builds this was the case -- that compiler was asked to solve an undecideable problem, when the assignment was dependent ( on other variable(s), as you name it ) on some operations / values that were not available at compile-time. Your motivation is clear and doable, however please try to design your code with this little level insights into the syntax-specifications and the principal differences between a code-compilation and a code-execution states.
Epilogue: Don't panic & Enjoy the worlds of algorithmic trading.

Live variable analysis , is my explanation correct?

As stackexchange have not more tags about compiler tags , so I'm posting here , this question .
A variable x is said to be live at a statement Si in a program if the following three conditions hold simultaneously :
1. There exists a statement Sj that uses x
2. There is a path from Si to Sj in the flow
graph corresponding to the program
3. The path has no intervening assignment to x
including at Si and Sj
The variables which are live both at the statement in basic block 2 and at the statement in basic block 3 of the above control flow graph are
p, s, u
r, s, u
r, u
q, v
I try to explain :
As the wikipedia says "Stated simply: a variable is live if it holds a value that may be needed in the future."
As per the definition given in question, a variable is live if it is used in future before any new assignment.
Block 2 has ‘r’ and ‘v’ both as live variables. as they are used in block 4 before any new value assinged to them. Note that variable ‘u’ is not live in block 2 as ‘u’ is assigned a new value in block 1 before it is used in block 3. Variables ‘p’, ‘s’ and ‘q’ are also not live in block 2 due to same reason.
Block 3 has only ‘r’ as live variable as every other variable is assigned a new value before use.
Another explanation given as :
Only r.
p, s and u are assigned to in 1 and there is no intermediate use of them before that. Hence p, s and u are not live in both 2 and 3.
q is assigned to in 4 and hence is not live in both 2 and 3.
v is live at 3 but not at 2.
Only r is live at both 2 and 3.
But official GATE key said both r and u.
I see two things that are probably at least part of your confusion.
First, in the list of conditions for live variables, there is no restriction stating that Si != Sj, so this makes the definitions a little imprecise in my mind.
The second is your assertion "Note that variable ‘u’ is not live in block 2 as ‘u’ is assigned a new value in block 1 before it is used in block 3."
The way I would look at this would be this:
Upon entry into block 2, before the statement v = r + u is
executed (imagine a no-op empty statement inserted as the entry to
each block, and another as the exit from the block), then both r
and u must be live, because there exists an upcoming statement
that uses both, and there is a path in the code from the entry to
that statement that contains no intermediate assignments to either.
Rather than imagining these extra empty statements, using the
original semantics of the definitions, then we're just talking about
the case where Si == Sj, because both refer to the v = r + u
statement - there is trivially a path from a statement to itself
containing no additional assignments in that sense. I find it easier
to think about it with the extra empty entry and exit statements,
though.
After the execution of v = r + u, however, at the imaginary
block exit empty statement, it is now safe to consider u as not
live (alternatively, dead), because nothing in block 4 uses it, and
it's reassigned in block 1 before it's ever used again in either
block 2 or 3.
So, part of the confusion seems to be thinking of whether a variable is live in a particular block, which doesn't really fit with the definitions - you need to think about whether a variable is live at the point of a particular statement. You could make the case that the variable u is both alive and dead in block 2, depending on whether you look at it before execution of the lone statement, or after...

The variable address in Objective C language

I know that if the computer is 64 bit, then a int variable occupy 4 bytes. I try to test this by the following code.
int c = 16;
int f = 11;
NSLog(#"&c = %p &f = %p", &c,&f);
and the output is:
&c = 0x7fff570c8a4c &f = 0x7fff570c8a48
The discrepancy is 4, does this mean that the variable occupy 4 bytes? Where is the pointer of int and the int variable store in computer, stack or heap? Do pointer and variable store in different places?
I want to understand why the discrepancy of 2 the address of int is 4.
I know that if the computer is 64 bit, then a int variable occupy 64/8=8 bytes.
This is not true in general. For example, 64-bit Windows systems use 32-bit ints.
Regardless, the locations of variables on the stack are somewhat arbitrary, and cannot be relied upon to determine anything about those variables' size. (It is true in this case that these variables occupy four bytes, but the same will not be true in all circumstances.) If you need to determine the "bit-ness" of a system within a program, consider taking the size of a pointer, e.g.
sizeof(void *)
This will always return 4 for systems which use 32-bit addresses, and 8 for systems which use 64-bit addresses.
Yes, it does mean the variable occupies 4 bytes. And the pointers you asked about are stored on the stack for the call to NSLog().