I am learning Fortran 90/95, and the book I am using had a discussion about the influence of line printers on the format statement. According to the book, the program uses the first character of the line to decide the line's position relative to the previous line (i.e. '1' starts a new page, '0' skips a line, '+' overwrites the previous line, and ' ' or any other character writes the new line below the previous line). I compiled and ran a simple program in the console to test this, but did not observe this behavior.
program test
integer :: i = 123
character(13) :: hello = 'Hello, World!'
100 format ('0','Count = ',I3)
write (*,*) hello
write (*,100) i
end program
The output is
Hello, World!
0Count = 123
where I would have expected
Hello, World!
Count = 123
Does anyone know why this is? Is this a legacy feature that is not used in Fortran 90/95? Is it specific behavior for a print to the console? I would like to know when (if ever) I need to declare a special first character in the format statement when writing.
My compiler is Force 2.0.9, which I believe is based on gfortran. I am running it on Windows 7, and the console is PowerShell.
Thanks for the help!
This was used in the 70s and even 80s with line printers in FORTRAN 77 and earlier ... but when did you last see a line printer? Any Fortran 90/95 book that teaches this feature should be thrown away.
This has already been answered on Stack Overflow: Are Fortran control characters (carriage control) still implemented in compilers?
This applies only to old "fixed form" Fortran (77 and earlier), not to the new "free form" Fortran (90 and later), when all commands had to be indented by 6 spaces. You can still use fixed-form with appropriate compiler flags. Sometimes this is even the default if the extension is .f rather than .f90.
Fortran 90/95 is much too recent for me, but I don't recall those formatting options from using FORTRAN in the seventies.
Nevertheless, I think it's a legacy feature, and the fact that you've got '+' to overwrite a line suggests the options are intended for output to a line printer not the console screen.
I am learning Fortran 90/95, and the book I am using had a discussion about the influence of line printers on the format statement. According to the book, the program uses the first character of the line to decide the line's position relative to the previous line (i.e. '1' starts a new page, '0' skips a line, '+' overwrites the previous line, and ' ' or any other character writes the new line below the previous line). I compiled and ran a simple program in the console to test this, but did not observe this behavior.
That is one of the legacy features of Fortran which is mostly ignored today, since (if nothing else) one does not print to printers directly. In any case, most compilers (I really couldn't say for gfortran specifically now, since I don't have it installed) have options to disregard that behaviour, and some of them ignore the first column by default. From what you've shown it is reasonable to assume your is one of them, so yes, you can ignore it.
Out of habit in regards to this practice, a lot of fortran programmers start any string with a blank or 1x in the write statement.
Related
I am checking assembly code of a program and would like to highlight a specific value:
gdb a.out
b main
run
s ... until where I want to focus my attention
x/32 0x555555554b80 display nicely the bytes
Now, is there a way to ask gdb to display the output AND highlight if a byte is equal to the desired value (here 0x27) ?
x/32 0x555555554b80 | 0x27
By highlighting I mean put this byte in bold or green, or whatever that makes it stands out!
PS: I am aware about this question but 1/ it does not answer my question, 2/ I would like to use gdb
There's no built-in way to do this. However, it can still be done with some scripting.
A relatively simple way, with a new-enough gdb, is to use the pipe command to pipe the output of x through a program that will do the highlighting you want. For example, GNU grep can colorize the match this way.
Other approaches are possible. For example you could write a new x-like command in Python, using gdb's Python API.
I have a problem. When the program reads a text file, it always get out of the line and crashed.
var f:text;
i,j,cs:byte;
a:array[0..10,0..10] of int64
begin
assign(f,'anything.txt');
reset(f);
cs:=0;
while eoln(f)=false do
begin
read(f,a[0,cs]);
inc(cs);
end;
close(f);
end.
Here is the content of anything.txt:
2 4 8 16
exitcode=201
You have not told us which compiler you are using.
In Delphi and Turbo Pascal which preceded it, run-time error 201 means "range check error". I don not still have Turbo Pascal installed but your program compiles and runs as a "console application" correctly in Delphi with only one minor change, namely to insert a semi-colon (';') after int64. It runs correctly whether the compiler has range-checking turned on or not.
It also runs correctly in FreePascal + Lazarus.
So, unless you are using a different compiler which also happens to have a run-time error code 201, your problem seems to be caused by something you have not included in your question. In any case you should learn to debug this kind of problem yourself. So:
Look up how to use use the debugger in your Pascal compiler. Place a breakpoint on the line inc(cs) e.g. by pressing F5and run the program. When it stops at the BP, place debug watches (using Ctrl-F5 in Delphi/TP) on the values of cs and a and observe the values carefully. Press F8 repeatedly to single step the program, and see if you can see where and why it goes wrong.
One possibility for what is causing your problem is that you are not reading the copy on anything.txt you think you are: because you don't include a path to the file in assign(f Windows will use the copy of anything.txt, if any, in whatever it thinks the current directory is. To avoid this, include the path to where the file is, as in
assign(f, 'C:\PascalData\Anything.Txt');
Also btw, you don't need to compare a boolean function (or expression) againt true or false as in
while eoln(f)=false do
Instead you can simply do
while not eoln(f) do
I'm using Fortran for my research and sometimes, for debugging purposes, someone will insert in the code something like this:
write(*,*) 'Variable x:', varx
The problem is that sometimes it happens that we forget to remove that statement from the code and it becomes difficult to find where it is being printed. I usually can get a good idea where it is by the name 'Variable x' but it sometimes happens that that information might no be present and I just see random numbers showing up.
One can imagine that doing a grep for write(*,*) is basically useless so I was wondering if there is an efficient way of finding my culprit, like forcing every call of write(*,*) to print a file and line number, or tracking stdout.
Thank you.
Intel's Fortran preprocessor defines a number of macros, such as __file__ and __line__ which will be replaced by, respectively, the file name (as a string) and line number (as an integer) when the pre-processor runs. For more details consult the documentation.
GFortran offers similar facilities, consult the documentation.
Perhaps your compiler offers similar capabilities.
As has been previously implied, there's no Fortran--although there may be a compiler approach---way to change the behaviour of the write statement as you want. However, as your problem is more to do with handling (unintentionally produced) bad code there are options.
If you can't easily find an unwanted write(*,*) in your code that suggests that you have many legitimate such statements. One solution is to reduce the count:
use an explicit format, rather than list-directed output (* as the format);
instead of * as the output unit, use output_unit from the intrinsic module iso_fortran_env.
[Having an explicit format for "proper" output is a good idea, anyway.]
If that fails, use your version control system to compare an old "good" version against the new "bad" version. Perhaps even have your version control system flag/block commits with new write(*,*)s.
And if all that still doesn't help, then the pre-processor macros previously mentioned could be a final resort.
I have a big, old, FORTRAN 77 code that has worked for many, many years with no problems.
Double-precision is not enough anymore, so to convert to quadruple-precision I have:
Replaced all occurrences of REAL*8 to REAL*16
Replaced all functions like DCOS() into functions like COS()
Replaced all built-in numbers like 0.d0 to 0.q0 , and 1D+01 to 1Q+01
The program compiles with no errors or warnings with the gcc-4.6 compiler on
operating system: openSUSE 11.3 x86_64 (a 64-bit operating system)
hardware: Intel Xeon E5-2650 (Sandy Bridge)
My LD_LIBRARY_PATH variable is set to the 64-bit library folder:
/gcc-4.6/lib64
The program reads an input file that has numbers in it.
Those numbers used to be of the form 1.234D+02 (for the double-precision version of the code, which works).
I have changed them so now that number is 1.234Q+02 , however I get the runtime error:
Bad real number in item 1 of list input
Indicating that the subroutine that reads in the data from the input file (called read.f) does not find the first number in the inputfile, to be compatible with what it expected.
Strangely, the quadruple-precision version of the code does not complain when the input file contains numbers like 1.234D+02 or 123.4 (which, based on the output seems to automatically be converted to the form 1.234D+02 rather than Q+02), it just does not like the Q+02 , so it seems that gcc-4.6 does not allow quadruple-precision numbers to be read in from input files in scientific notation !
Has anyone ever been able to read from an input file a quadruple-precision number in scientific notation (ie, like 1234Q+02) in FORTRAN with a gcc compiler, and if so how did you get it to work ? (or did you need a different compiler/operating system/hardware to get it to work ?)
Almost all of this is already in comments by #IanH and #Vladimi.
I suggest mixing in a little Fortran 90 into your FORTRAN 77 code.
Write all of your numbers with "E". Change your other program to write the data this way. Don't bother with "D" and don't try to use the infrequently supported "Q". (Using "Q" in constants in source code is an extension of gfortran -- see 6.1.8 in manual.)
Since you want the same source code to support two precisions, at the top of the program, have:
use ISO_FORTRAN_ENV
WP = real128
or
use ISO_FORTRAN_ENV
WP = real64
as the variation that changes whether your code is using double or quadruple precision. This is using the ISO Fortran Environment to select the types by their number of bits. (use needs to between program and implicit none; the assignment statement after implicit none.)
Then declare your real variables via:
real (WP) :: MyVar
In source code, write real constants as 1.23456789012345E+12_WP. The _type is the Fortran 90 way of specifying the type of a constant. This way you can go back and forth between double and quadruple precision by only changing the single line defining WP
WP == Working Precision.
Just use "E" in input files. Fortran will read according to the type of the variable.
Why not write a tiny test program to try it out?
I am working on a code parser that is built on Rexx. It is a single file script with around 5000 lines of code or more. I've never worked on Rexx before. Adding to that, the readability issue is making my life even tougher. So,
Are there are any tools to debug and understand Rexx code?
Use the trace statement? The most simple mode of tracing is 'A'. This causes each instruction to be displayed before it is executed. Your instruction is displayed with a line number and the three characters - preceding it, so that you can identify it as a line in your script.
Wikipedia has a pretty good article on Rexx, which should help you understand Rexx syntax and program structure. And almost any Rexx book will apply to your environment, because Rexx is extremely cross-system (similar in that way to the younger Perl and Python languages). There aren't a lot of online books, because almost everything written about Rexx was written before the web existed, but the reference manual for the Regina implementation is, and it's a particularly good reference work.
The date on this question is old, but I'll share what I have found helpful for the next person who pulls this up.
Already mentioned is the TRACE option. I've found this can be overwhelming in a small set of code let alone 5,000 lines or more.Here are some options I've found useful:
Use an "if" to turn the trace on only in certain situations.if counter < 25 then trace "A" Be sure to turn the trace off with:else trace "OFF"
Use say followed by pull. What is said will stay on the screen until you hit enter.
Add a subroutine:
AskIt:
parse pull comment
say comment
say 'enter "X" to exit program'
pull continueif Continue \= "X" then returnexit
This is invoked with call AskIt "In routine that loops, counter=" counter and would display: In routine that loops counter='##enter "X" to exit programThe tester chooses to return to the code by hitting enter or exit the program with X to edit the source.Temporarily inserting return on the line following the routine label will allow you to run the code uninterrupted without removing all the calls.
I have written an edit macro for z/OS which inserts a say *routine name* after every routine label. It inserts the code with a /* comment */ containing a readily identified phrase to simplify cleanup.The audience for this would be small, so I'll not include the code here.
Hope this helps someone.