Skipping lines in Fortran - if-statement

What lines are read in an Fortran IF-statement? I wondered which of these three lines will be read depending on the IF-statement outcome:
IF (x.GT.y) GOTO 100
x= y+1
100 x = y
Will the indexed row 100 always be read? Or is it skipped if the IF-statement returns True and x= y+1 is stored?

The three lines in the example form three distinct executable statements. They are not part of a single IF statement.
The IF statement is formed from the single (non-continued) line
IF (x.GT.y) GOTO 100
Once the IF statement has been executed, the flow of execution either moves on to the next line/statement (if the condition is false) or jumps to the statement labelled 100 (if true). Once execution has flowed, the IF statement exerts no further influence.
If execution reaches the second statement there is no further flow control to stop execution reaching the third statement (other than any defined assignment, defined + operator, or error caused by the evaluation of the right-hand side, etc).
On reaching the third line:
recall that the IF statement is in the long-forgotten past: the label 100 and the "jump target" are irrelevant to the present
the statement having a label does not change how the statement is evaluated (just how it can be reached).
That is, there is nothing which says "this line should be treated in a special way".
Yes, the third line will ("always") be executed in full.

Related

What is this "for" syntax called? [duplicate]

I have seen some very weird for loops when reading other people's code. I have been trying to search for a full syntax explanation for the for loop in C but it is very hard because the word "for" appears in unrelated sentences making the search almost impossible to Google effectively.
This question came to my mind after reading this thread which made me curious again.
The for here:
for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
In the middle condition there is a comma separating the two pieces of code, what does this comma do? The comma on the right side I understand as it makes both a>>=1 and b<<=1.
But within a loop exit condition, what happens? Does it exit when p==0, when a==1 or when both happen?
It would be great if anyone could help me understand this and maybe point me in the direction of a full for loop syntax description.
The comma is not exclusive of for loops; it is the comma operator.
x = (a, b);
will do first a, then b, then set x to the value of b.
The for syntax is:
for (init; condition; increment)
...
Which is somewhat (ignoring continue and break for now) equivalent to:
init;
while (condition) {
...
increment;
}
So your for loop example is (again ignoring continue and break) equivalent to
p=0;
while (p+=(a&1)*b,a!=1) {
...
a>>=1,b<<=1;
}
Which acts as if it were (again ignoring continue and break):
p=0;
while (true) {
p+=(a&1)*b;
if (a == 1) break;
...
a>>=1;
b<<=1;
}
Two extra details of the for loop which were not in the simplified conversion to a while loop above:
If the condition is omitted, it is always true (resulting in an infinite loop unless a break, goto, or something else breaks the loop).
A continue acts as if it were a goto to a label just before the increment, unlike a continue in the while loop which would skip the increment.
Also, an important detail about the comma operator: it is a sequence point, like && and || (which is why I can split it in separate statements and keep its meaning intact).
Changes in C99
The C99 standard introduces a couple of nuances not mentioned earlier in this explanation (which is very good for C89/C90).
First, all loops are blocks in their own right. Effectively,
for (...) { ... }
is itself wrapped in a pair of braces
{
for (...) { ... }
}
The standard sayeth:
ISO/IEC 9899:1999 §6.8.5 Iteration statements
¶5 An iteration statement is a block whose scope is a strict subset of the scope of its
enclosing block. The loop body is also a block whose scope is a strict subset of the scope
of the iteration statement.
This is also described in the Rationale in terms of the extra set of braces.
Secondly, the init portion in C99 can be a (single) declaration, as in
for (int i = 0; i < sizeof(something); i++) { ... }
Now the 'block wrapped around the loop' comes into its own; it explains why the variable i cannot be accessed outside the loop. You can declare more than one variable, but they must all be of the same type:
for (int i = 0, j = sizeof(something); i < j; i++, j--) { ... }
The standard sayeth:
ISO/IEC 9899:1999 §6.8.5.3 The for statement
The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: The expression expression-2 is the controlling expression that is
evaluated before each execution of the loop body. The expression expression-3 is
evaluated as a void expression after each execution of the loop body. If clause-1 is a
declaration, the scope of any variables it declares is the remainder of the declaration and
the entire loop, including the other two expressions; it is reached in the order of execution
before the first evaluation of the controlling expression. If clause-1 is an expression, it is
evaluated as a void expression before the first evaluation of the controlling expression.133)
Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a
nonzero constant.
133) Thus, clause-1 specifies initialization for the loop, possibly declaring one or more variables for use in
the loop; the controlling expression, expression-2, specifies an evaluation made before each iteration,
such that execution of the loop continues until the expression compares equal to 0; and expression-3
specifies an operation (such as incrementing) that is performed after each iteration.
The comma simply separates two expressions and is valid anywhere in C where a normal expression is allowed. These are executed in order from left to right. The value of the rightmost expression is the value of the overall expression.
for loops consist of three parts, any of which may also be empty; one (the first) is executed at the beginning, and one (the third) at the end of each iteration. These parts usually initialize and increment a counter, respectively; but they may do anything.
The second part is a test that is executed at the beginning of each execution. If the test yields false, the loop is aborted. That's all there is to it.
The C style for loop consists of three expressions:
for (initializer; condition; counter) statement_or_statement_block;
The initializer runs once, when the loop starts.
The condition is checked before each iteration. The loop runs as long it evaluates to true.
The counter runs once after each iteration.
Each of these parts can be an expression valid in the language you write the loop in. That means they can be used more creatively. Anything you want to do beforehand can go into the initializer, anything you want to do in between can go into the condition or the counter, up to the point where the loop has no body anymore.
To achieve that, the comma operator comes in very handy. It allows you to chain expressions together to form a single new expression. Most of the time it is used that way in a for loop, the other implications of the comma operator (e.g. value assignment considerations) play a minor role.
Even though you can do clever things by using syntax creatively - I would stay clear of it until I find a really good reason to do so. Playing code golf with for loops makes code harder to read and understand (and maintain).
The wikipedia has a nice article on the for loop as well.
Everything is optional in a for loop. We can initialize more than one variable, we can check for more than one condition, we can iterate more than one variable using the comma operator.
The following for loop will take you into an infinite loop. Be careful by checking the condition.
for(;;)
Konrad mentioned the key point that I'd like to repeat: The value of the rightmost expression is the value of the overall expression.
A Gnu compiler stated this warning when I put two tests in the "condition" section of the for loop
warning: left-hand operand of comma expression has no effect
What I really intended for the "condition" was two tests with an "&&" between. Per Konrad's statement, only the test on to the right of the comma would affect the condition.
the for loop is execution for particular time for(;;)
the syntex for for loop
for(;;)
OR
for (initializer; condition; counter)
e.g (rmv=1;rmv<=15;rmv++)
execution to 15 times in for block
1.first initializ the value because start the value
(e.g)rmv=1 or rmv=2
2.second statement is test the condition is true or false ,the condition true no.of time execution the for loop and the condition is false terminate for block,
e.g i=5;i<=10 the condition is true
i=10;i<10 the condition is false terminate for block,
3.third is increment or decrement
(e.g)rmv++ or ++rmv

MARIE Assembly if else

Struggle with MARIE Assembly.
Needing to write a code that has x=3 and y=5, is x>y then it needs to output 1, if x<y it needs to output one,
I have the start but don't know how to do if else statements in MARIE
LOAD X
SUBT Y
SKIPCOND 800
JUMP ELSE
OUTPUT
HALT
Structured statements have a pattern, and each one has an equivalent pattern in assembly language.
The if-then-else statement, for example, has the following pattern:
if ( <condition> )
<then-part>
else
<else-part>
// some statement after if-then-else
Assembly language uses an if-goto-label style.  if-goto is a conditional test & branch; and goto alone is an unconditional branch.  These forms alter the flow of control and can be composed to do the same job as structure statements.
The equivalent pattern for the if-then-else in assembly (but written in pseudo code) is as follows:
if ( <condition> is false ) goto if1Else;
<then-part>
goto if1Done;
if1Else:
<else-part>
if1Done:
// some statement after if-then-else
You will note that the first conditional branch (if-goto) needs to branch on condition false.  For example, let's say that the condition is x < 10, then the if-goto should read if ( x >= 10 ) goto if1Else;, which branches on x < 10 being false.  The point of the conditional branch is to skip the then-part (to skip ahead to the else-part) when the condition is false — and when the condition is true, to simply allow the processor to run the then-part, by not branching ahead.
We cannot allow both the then-part and the else-part to execute for the same if-statement's execution.  The then-part, once completed, should make the processor move on to the next statement after the if-then-else, and in particular, to avoid the else-part, since the then-part just fired.  This is done using an unconditional branch (goto without if), to skip ahead around the else-part — if the then-part just fired, then we want the processor to unconditionally skip the else-part.
The assembly pattern for if-then-else statement ends with a label, here if1Done:, which is the logical end of the if-then-else pattern in the if-goto-label style.  Many prefer to name labels after what comes next, but these labels are logically part of the if-then-else, so I choose to name them after the structured statement patterns rather than about subsequent code.  Hopefully, you follow the assembly pattern and see that whether the if-then-else runs the then-part or the else-part, the flow of control comes back together to run the next line of code after the if-then-else, whatever that is (there must be a statement after the if-then-else, because a single statement alone is just a snippet: an incomplete fragment of code that would need to be completed to actually run).
When there are multiple structured statements, like if-statements, each pattern translation must use its own set of labels, hence the numbering of the labels.
(There are optimizations where labels can be shared between two structured statements, but doing that does not optimize the code in any way, and makes it harder to change.  Sometimes nested statements can result in branches to unconditional branches — since these actual machine code and have runtime costs, they can be optimized, but such optimizations make the code harder to rework so should probably be held off until the code is working.)
When two or more if-statements are nested, the pattern is simply applied multiple times.  We can transform the outer if statement first, or the inner first, as long as the pattern is properly applied, the flow of control will work the same in assembly as in the structured statement.
In summary, first compose a larger if-then-else statement:
if ( x < y )
Output(1)
else
Output(one)
(I'm not sure this is what you need, but it is what you said.)
Then apply the pattern transformation into if-goto-label: since, in the abstract, this is the first if-then-else, let's call it if #1, so we'll have two labels if1Done and if1Else.  Place the code found in the structured pattern into the equivalent locations of the if-goto-label pattern, and it will work the same.
MARIE uses SkipCond to form the if-goto statement.  It is typical of machine code to have separate compare and branch instructions (as for a many instruction set architectures, there are too many operands to encode an if goto in a single instruction (if x >= y goto Label; has x, y, >=, and Label as operands/parameters).  MARIE uses subtract and branch relative to 0 (the SkipCond).  There are other write-ups on the specific ways to use it so I won't go into that here, though you have a good start on that already.

A single C++ variable has conflicting values in debugger?

Please see the screenshot below. I noticed some erroneous results in my code so I went to debug.
As you can see, I put a break point when the variable 'latest' is equal to "5". BUT, apparently the application is hitting on this break point even thought 'latest' is equal to "2", not "5". Any idea what is going on here?
Format your code like this (>> denoting the breakpoint):
if (latest == "5")
{
>> ;
}
rather than this:
>> if (latest == "5") {;}
In the latter case the breakpoint is at the if, not at the ; inside the {}.
Cramming too many statements on the same line makes step by step debugging painful and makes the code less readable.
I put a break point when the variable latest is equal to "5"
No, you put a breakpoint where the variable latest is compared to "5". The comparison has to happen before the if statement knows which branch to take.
Your code rather than this:
if (latest == "5") {;}
Only use single-line if statements on a single line
The problem occurs when a single-line if the statement is broken up into two lines. While the compiler sees this as one statement guarded by a single condition, humans often accidentally read this is an if block, whether there are curly braces or not, thanks to the indentation. Humans notice the indentation, the compiler does not.
if (latest == "5")
;
If the statement you’re guarding is small, and not worth the extra heft of curly braces, just put it on the same line.

Fortran does if stop need an endif?

In fortran 90, does an if stop statement require a closing endif?
example:
if(foo.eq.1) stop
!do some stuff
Is do some stuff part of the loop or does stop imply endif as the program is ended?
There are mainly two places (apart from the arithmetic if) where the if keyword can be met.
Firstly it is the logical if statement
if (condition) statement_if_true
If the condition is true, the statement_if_true is executed. Anything that follows is not part of the if statement. There is no then and no end if here.
Secondly there is the if conditional construct
if (condition) then
body with statements
end if
The body can contain any number of statements or constructs and must be followed by end if. The then keyword is obligatory for the construct and the body begins on a new line after the then.

Data block Fortran 77 clarification

I am trying to access a data block, the way it is define is as follows
DATA NAME /'X1','X2','X3','X4','X5','X6','X7','X8','X9','10','11',00028650
1'12','13','14','15','16','17','18','19','20','21','22','23','24'/ 00028660
The code is on paper. Note this is an old code, the only thing i am trying to do is understand how the array is being indexed. I am not trying to compile it.
The way it is accessed is as follows
I = 0
Loop
I = I + 1
write (06,77) (NAME(J,I),J=1,4) //this is inside a write statement.
end loop //77 is a format statement.
Not sure how it is being indexed, if you guys can shed some light that would be great.
The syntax (expr, intvar=int1,int2[,int3]) widely refers to an implied DO loop. There are several places where such a thing may occur, and an input/output statement is one such place.
An implied DO loop evaluates the expression expr with the do control integer variable intvar sequentially taking the values initially int1 in steps of int3 until the value int2 is reached/passed. This loop control is exactly as one would find in a do loop statement.
In the case of the question, the expression is name(j,i), the integer variable j is the loop variable, taking values between the bounds 1 and 4. [The step size int3 is not provided so is treated as 1.] The output statement is therefore exactly like
write(6,77) name(1,i), name(2,i), name(3,i), name(4,i)
as we should note that elements of the implied loop are expanded in order. i itself comes from the loop containing this output statement.
name here may refer to a function, but given the presence of a data statement initializing it, it must somehow be declared as a rank-2 (character) array. The initialization is not otherwise important.