|
|||
|
I was looking at this web page of best practices in Fortran
http://fortran90.org/src/best-practices.html#arrays and it shows this code fragment: ----------------------------- subroutine f(r) real(dp), intent(in) :: r( ![]() integer :: n, i n = size(r) do i = 1, n r(i) = 1.0_dp / i**2 enddo end subroutine -------------------------- The first strange thing I noticed is that the formal parameter r is declared as 'in' yet it is being written to inside the subroutine. But based on Fortran standard: "intent(in) means that the variable value can enter, but not be changed" So, what is going on here? When I tried it on my end, I am getting an error. Here is my code to test the above. all in same one file. ------------ t6.f90 ------------------------- module inc implicit none contains subroutine f(r) integer, parameter:: dp=kind(0.d0) real(dp), intent(in) :: r( ![]() integer :: n, i n = size(r) do i = 1, n r(i) = 1.0_dp / i**2 enddo end subroutine f end module inc program main use inc implicit none integer, parameter:: dp=kind(0.d0) real(dp) :: r(5) call f(r) end program main ---------------------------- --------------------------- >gfortran -fcheck=all -Wall t6.f90 t6.f90:11.10: r(i) = 1.0_dp / i**2 1 Error: Dummy argument 'r' with INTENT(IN) in variable definition context (assignment) at (1) t6.f90:17.8: use inc 1 Fatal Error: Can't open module file 'inc.mod' for reading at (1): No such file or directory > ------------------------------ Am I doing something wrong? could the web page really be wrong? Has the standard changed and once it was allowed to write to an 'in' parameter? does not make much sense. I am not good enough in Fortran to say that a Fortran90.org 'best practices' page is wrong ! But it sure looks like it. thanks, --Nasser |
|
|
||||
|
||||
|
|
|
|||
|
Nasser M. Abbasi <nma@12000.org> wrote:
> I was looking at this web page of best practices in Fortran > > http://fortran90.org/src/best-practices.html#arrays > > and it shows this code fragment: > > ----------------------------- > subroutine f(r) > real(dp), intent(in) :: r( ![]() > integer :: n, i > n = size(r) > do i = 1, n > r(i) = 1.0_dp / i**2 > enddo > end subroutine > -------------------------- > > The first strange thing I noticed is that the formal > parameter r is declared as 'in' yet it is being written > to inside the subroutine. But based on Fortran standard: .... > I am not good enough in Fortran to say that a Fortran90.org > 'best practices' page is wrong ! But it sure looks like it. Yes, that is a clear error in that web page. Do note that the web page in question is mostly the effort of one individual. It isn't as though it is anything official or widely vetted. Of course, it can have errors. (It also has a pretty explicitly stated slant towards people with a prior background in Python, which largely leaves me out). While certainly a worthwhile effort, my biggest comment would be that it is pretty narrow. There are a *LOT* of other things I would personally consider to be best practices. But then I'm in no position to criticize; it isn't as though I've put in the work to write up something more comprehensive. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain |
|
|||
|
On 6/23/2012 8:32 PM, Nasser M. Abbasi wrote:
.. > I am not good enough in Fortran to say that a Fortran90.org > 'best practices' page is wrong ! But it sure looks like it. Yes. Unless of course they were listing test cases for the compilers error detection capability! (I didn't look it up.. so I don't know why they wrote it.) BTW: what was the second strange thing? -- Jos |
|
|||
|
On 6/23/2012 1:55 PM, Jos Bergervoet wrote:
> > BTW: what was the second strange thing? > This: "Integer Division (N - 1.0_dp)/N As long as one of the / operands is a float, a floating point division will be used." I found this behavior really strange and can lead to errors. -------------------------- program main implicit none integer, parameter:: dp=kind(0.d0) integer, parameter:: N=3 real(dp) :: r r = (N-1)/N Print *,r end program main ----------------------- >gfortran -fcheck=all -Wall t7.f90 >./a.out 0.0000000000000000 Because one 'forgot' to make 'one' of the variables in that line real. The compiler did not even warn about it. Compare this to Ada: ---------------------- procedure foo is N : integer := 3; r : float; begin r := (N-1)/N; end foo; ---------------------- >gnatmake foo.adb gcc-4.6 -c foo.adb foo.adb:5:14: expected type "Standard.Float" foo.adb:5:14: found type "Standard.Integer" gnatmake: "foo.adb" compilation error > The program will not even compile. Which is good. Ada wants an explicit cast, else will not compile. So, what I found strange is a rule which says "As long as ". Whenever I read things like this, I get really nervous. I keep worrying about a bridge falling, or something like this becuase I forgot to add _dp to 'one' of the parmaters in that line above. --Nasser |
|
|||
|
On 2012-06-23 16:48:56 -0300, Nasser M. Abbasi said:
> On 6/23/2012 1:55 PM, Jos Bergervoet wrote: > >> >> BTW: what was the second strange thing? >> > > This: > > "Integer Division > (N - 1.0_dp)/N > > As long as one of the / operands is a float, a floating > point division will be used." > > I found this behavior really strange and can lead to errors. Mixed mode is a problematic area. Perhaps this tells you something about the quality of the "best practices" site you are looking at. The internet is like that. The cynics in the crowd would probably say it was put there by some starting student with too much time on their hands. You can check to see if it has had much updating after it was started. It is not a good sign if it has a few updates right after it started and none for the last several years. Or if there is only one author. Once you have accumulated some amount of scar tissue from making dumb mistakes you learn to not play games with mixed mode. Fortran is very old so for historical continuity reasons permits the users to play with fire. Other languages with less history, and much smaller libraries of useful stuff, provide less access to the fire. > -------------------------- > program main > implicit none > > integer, parameter:: dp=kind(0.d0) > integer, parameter:: N=3 > real(dp) :: r > > r = (N-1)/N > Print *,r > end program main > ----------------------- > >> gfortran -fcheck=all -Wall t7.f90 >> ./a.out > 0.0000000000000000 > > Because one 'forgot' to make 'one' of the variables > in that line real. The compiler did not even warn about it. > > Compare this to Ada: > > ---------------------- > procedure foo is > N : integer := 3; > r : float; > begin > r := (N-1)/N; > end foo; > ---------------------- > >> gnatmake foo.adb > gcc-4.6 -c foo.adb > foo.adb:5:14: expected type "Standard.Float" > foo.adb:5:14: found type "Standard.Integer" > gnatmake: "foo.adb" compilation error >> > > The program will not even compile. Which is good. Ada > wants an explicit cast, else will not compile. > > So, what I found strange is a rule which says > "As long as ". Whenever I read things like this, I get > really nervous. I keep worrying about a bridge falling, or > something like this becuase I forgot to add _dp to 'one' > of the parmaters in that line above. > > --Nasser |
|
|||
|
Nasser M. Abbasi wrote:
> -------------------------- > program main > implicit none > > integer, parameter:: dp=kind(0.d0) > integer, parameter:: N=3 > real(dp) :: r > > r = (N-1)/N > Print *,r > > end program main > ----------------------- > >> gfortran -fcheck=all -Wall t7.f90 >> ./a.out > 0.0000000000000000 > > Because one 'forgot' to make 'one' of the variables > in that line real. The compiler did not even warn about it. Unfortunately, there is too many valid code to warn in cases like you had. Such code has typically the form: complex = real ! esp. "0.0" real = integer ! esp. "0" or some loop variable Thus, any attempt to warn for those will produce way to many warning to be useful in the general case. Actually, gfortran provides two kind of warnings: -Wconversion which is implied by -Wall. That one produces only few warnings which mostly point to bugs. And -Wconversion-extra which can be handy to find bugs of the kind you had in your code. However, that flag will produce tons of false positives in real-world code. (But I managed to find real issues with that flag, hidden in about a thousand warning lines.) For your program, gfortran gives with the -Wconversion-extra flag: r = (N-1)/N 1 Warning: Conversion from INTEGER(4) to REAL(8) at (1) Tobias |
|
|||
|
Gordon Sande <Gordon.Sande@gmail.com> wrote:
(snip) >> "Integer Division >> (N - 1.0_dp)/N >> As long as one of the / operands is a float, a floating >> point division will be used." >> I found this behavior really strange and can lead to errors. A favorite programming problem for new programmers is a temperature conversion table between C and F or F and C. If not before, that is usually when one learns about integer division and, usually, doesn't forget after that. (Not that one never slips up, which is different from not forgetting.) > Mixed mode is a problematic area. Perhaps this tells you something > about the quality of the "best practices" site you are looking at. > The internet is like that. The cynics in the crowd would probably say > it was put there by some starting student with too much time on their > hands. You can check to see if it has had much updating after it was > started. It is not a good sign if it has a few updates right after it > started and none for the last several years. Or if there is only one > author. It might be using examples of how not to do it to teach how best to do it. (I haven't looked at the site at all.) I high-school I remember an assignment to write an essay using as many cliches as we could. That would help remind us not to use them in our writing later. > Once you have accumulated some amount of scar tissue from making dumb > mistakes you learn to not play games with mixed mode. Fortran is very > old so for historical continuity reasons permits the users to play > with fire. Other languages with less history, and much smaller libraries > of useful stuff, provide less access to the fire. Well, many other languages followed the mixed-mode rules from Fortran. C does it pretty much the same way. Java has some special rules related to widening and narrowing conversions that will prevent some of the errors that one might make in Fortran or C. Assigning an expression to a variable with a narrower range requires a cast. (Range, not precision, so you can assign int to float without a cast, but not the other way.) -- glen |
|
|||
|
On Jun 24, 4:32*am, "Nasser M. Abbasi" <n...@12000.org> wrote:
> I was looking at this web page of best practices in Fortran > > http://fortran90.org/src/best-practices.html#arrays > > and it shows this code fragment: > > ----------------------------- > subroutine f(r) > real(dp), intent(in) :: r( ![]() > integer :: n, i > n = size(r) > do i = 1, n > * * *r(i) = 1.0_dp / i**2 > enddo > end subroutine > -------------------------- > > The first strange thing I noticed is that the formal > parameter r is declared as 'in' yet it is being written > to inside the subroutine. But based on Fortran standard: > > "intent(in) means that the variable value can enter, but not be changed" > > So, what is going on here? > > When I tried it on my end, I am getting an error. > > Here is my code to test the above. all in same one file. > > ------------ t6.f90 ------------------------- > module inc > * *implicit none > * *contains > > * * *subroutine f(r) > * * * *integer, parameter:: dp=kind(0.d0) > * * * *real(dp), intent(in) :: r( ![]() > * * * *integer :: n, i > * * * *n = size(r) > * * * *do i = 1, n > * * * * * *r(i) = 1.0_dp / i**2 > * * * enddo > * * *end subroutine f > end module inc > > program main > * use inc > * implicit none > > * integer, parameter:: dp=kind(0.d0) > * real(dp) :: r(5) > * call f(r) > > end program main > ---------------------------- > > --------------------------->gfortran -fcheck=all -Wall t6.f90 > > t6.f90:11.10: > > * * * * * *r(i) = 1.0_dp / i**2 > * * * * * *1 > Error: Dummy argument 'r' with INTENT(IN) in variable definition context (assignment) at (1) > t6.f90:17.8: > > * use inc > * * * * *1 > Fatal Error: Can't open module file 'inc.mod' for reading at (1): No suchfile or directory > > ------------------------------ > > Am I doing something wrong? could the web page really be wrong? > Has the standard changed and once it was allowed to write > to an 'in' parameter? does not make much sense. > > I am not good enough in Fortran to say that a Fortran90.org > 'best practices' page is wrong ! But it sure looks like it. It is. An INTENT(IN) dummy argument is not to be assigned. And that's not the only thing that is suspect. 1.0_dp / i**2 isn't a good way to write the expression 1/i**2. When i is large, i**2 will overflow without warning. Thus, it should have been written 1/real(i, dp)**2 |
|
|||
|
On Sunday, 24 June 2012 05:48:56 UTC+10, Nasser M. Abbasi wrote:
> On 6/23/2012 1:55 PM, Jos Bergervoet wrote: > > > > > BTW: what was the second strange thing? > > > > This: > > "Integer Division > (N - 1.0_dp)/N > > As long as one of the / operands is a float, a floating > point division will be used." > > I found this behavior really strange and can lead to errors. > > -------------------------- > program main > implicit none > > integer, parameter:: dp=kind(0.d0) > integer, parameter:: N=3 > real(dp) :: r > > r = (N-1)/N > Print *,r > > end program main > ----------------------- > > >gfortran -fcheck=all -Wall t7.f90 > >./a.out > 0.0000000000000000 > > Because one 'forgot' to make 'one' of the variables > in that line real. The compiler did not even warn about it. In PL/I, (N-1)/N gives 0.6666666666, as you would expect. > Compare this to Ada: > > ---------------------- > procedure foo is > N : integer := 3; > r : float; > begin > r := (N-1)/N; > end foo; > ---------------------- > > >gnatmake foo.adb > gcc-4.6 -c foo.adb > foo.adb:5:14: expected type "Standard.Float" > foo.adb:5:14: found type "Standard.Integer" > gnatmake: "foo.adb" compilation error > > The program will not even compile. Which is good. Ada > wants an explicit cast, else will not compile. > > So, what I found strange is a rule which says > "As long as ". Whenever I read things like this, I get > really nervous. I keep worrying about a bridge falling, or > something like this becuase I forgot to add _dp to 'one' > of the parmaters in that line above. |
|
|||
|
On 6/23/2012 11:07 PM, Tobias Burnus wrote:
> Nasser M. Abbasi wrote: >> -------------------------- >> program main >> implicit none >> >> integer, parameter:: dp=kind(0.d0) >> integer, parameter:: N=3 >> real(dp) :: r >> >> r = (N-1)/N >> Print *,r >> >> end program main >> ----------------------- >> >>> gfortran -fcheck=all -Wall t7.f90 >>> ./a.out >> 0.0000000000000000 >> >> Because one 'forgot' to make 'one' of the variables >> in that line real. The compiler did not even warn about it. > > Unfortunately, there is too many valid code to warn in cases like you > had. Such code has typically the form: > > complex = real ! esp. "0.0" > real = integer ! esp. "0" or some loop variable No, that's widening and is the opposite of what the complaint here is about! A similar problem with complex does ,however, exist. A list of them: integer :: i real :: x complex :: c = (1.0, 2.0) x = c ! <-- should give error/warning !!! i = x ! <-- should give error/warning !!! x = 1/2 ! <-- should give error, warning or 0.5 > Thus, any attempt to warn for those will produce way to many warning to > be useful in the general case. A clever way to introduce the warnings only for the new declaration style '::' could have been introduced in f90. But they didn't.. Now it's error prone. -- Jos |
|
|||
|
On 6/23/2012 9:48 PM, Nasser M. Abbasi wrote:
> On 6/23/2012 1:55 PM, Jos Bergervoet wrote: > >> >> BTW: what was the second strange thing? >> > > This: > > "Integer Division > (N - 1.0_dp)/N > > As long as one of the / operands is a float, a floating > point division will be used." > > I found this behavior really strange and can lead to errors. > > -------------------------- > program main > implicit none > > integer, parameter:: dp=kind(0.d0) > integer, parameter:: N=3 > real(dp) :: r > > r = (N-1)/N > Print *,r > > end program main > ----------------------- > >> gfortran -fcheck=all -Wall t7.f90 >> ./a.out > 0.0000000000000000 > > Because one 'forgot' to make 'one' of the variables > in that line real. The compiler did not even warn about it. > > Compare this to Ada: Yes, and many other languages too! But C-like stuff and fortran does the rounding to zero. I complained about that long ago.. -- Jos |
|
|||
|
On Sunday, 24 June 2012 17:12:24 UTC+10, Jos Bergervoet wrote:
> On 6/23/2012 11:07 PM, Tobias Burnus wrote: > > Nasser M. Abbasi wrote: > > Unfortunately, there is too many valid code to warn in cases like you > > had. Such code has typically the form: > > > > complex = real ! esp. "0.0" > > real = integer ! esp. "0" or some loop variable > > No, that's widening and is the opposite of what the > complaint here is about! A similar problem with > complex does ,however, exist. A list of them: > > integer :: i > real :: x > complex :: c = (1.0, 2.0) > > x = c ! <-- should give error/warning !!! > i = x ! <-- should give error/warning !!! > x = 1/2 ! <-- should give error, warning or 0.5 > > > Thus, any attempt to warn for those will produce way to many warning to > > be useful in the general case. > > A clever way to introduce the warnings only for > the new declaration style '::' could have been > introduced in f90. But they didn't.. Now it's > error prone. An error/warning message could still be given for expressions like 1/2 etc. Warnings could also be given for the other two cases. |
|
|||
|
Jos Bergervoet wrote:
> On 6/23/2012 11:07 PM, Tobias Burnus wrote: >> Nasser M. Abbasi wrote: >>> -------------------------- >>> integer, parameter:: N=3 >>> real(dp) :: r >>> r = (N-1)/N >>> >>>> gfortran -fcheck=all -Wall t7.f90 >>>> ./a.out >>> 0.0000000000000000 >>> >>> Because one 'forgot' to make 'one' of the variables >>> in that line real. The compiler did not even warn about it. >> >> Unfortunately, there is too many valid code to warn in cases like you >> had. Such code has typically the form: >> >> complex = real ! esp. "0.0" >> real = integer ! esp. "0" or some loop variable > > No, that's widening and is the opposite of what the > complaint here is about! Well, in the original code, the assignment of an integer to a real is also a kind of widening (even if there can be precision loss for large integers). At least there are many valid codes, where one has real_var = integer_index_var Additionally, widening is also not always correct. Think of the famous double precision :: x x = sqrt(2.0) The code is perfectly valid, however, the programmer probably intended to write "sqrt(2.0d0)". > A similar problem with complex does ,however, exist. A list of them: > > integer :: i > real :: x > complex :: c = (1.0, 2.0) > > x = c ! <-- should give error/warning !!! > i = x ! <-- should give error/warning !!! > x = 1/2 ! <-- should give error, warning or 0.5 There shouldn't be an error as Fortran allows it. However, gfortran warns for the first two with -Wconversion / -Wall. As written before, "x = 1" or similar occurs too often in valid code to warn with -Wall. (gfortran warns for it with -Wconversion-extra.) One could start a complicated heuristic, which takes into account what exactly is written on the right-hand side, e.g. warning if the RHS contains an integer division while the LHS has is a floating-point variable. But that starts to get rather complicated and is orthogonal to the way Fortran evaluates expressions: Namely, first evaluating the RHS without taking the LHS into account, before assigning to the LHS. (Side remark: Due to popular demand, gfortran supports real = z'FFFFF' where the RHS is evaluated as real(z'FFFFFF'), though gfortran falls back to regard the BOZ as integer as soon as the BOZ is in any kind of expression. Other compilers use a more complicated heuristics. Fortunately, Fortran 2003 allows to have BOZ literals as arguments to REAL, INT and CMPLX, which solves this issue.) * * * I want to additionally note that giving the proper warning/error messages is not that simple if a compiler wants to support everything from Fortran 66/77 (with legacy extensions) to Fortran 2008 code, where the latter could be also F66 code with few F2008 features. Mere users usually prefer no errors/warnings and even if the compiler points out a real problem, they rather like to have it swept under the carpet rather than to think about solving the issue. Developers of modern code would like to have strict checking and extensive warnings (but without false positives!),* but also be able to sweep some issues under the carpet, e.g. by getting away when using a certain vendor extension - or construct from a newer version of the standard.** The whole is complicated by the fact that most compiler users do not read the manual. The maximal one can expect that they know about -O<n> for optimization, "-g" for debugging symbols, some way of turning on the standard diagnostic (e.g. -std=f2003 or -stand f03 or ...), some default-set of warnings (-Wall, -warn all, -w=all, ...) and turning bound/other run-time checks on (-fcheck=all, -check all, -C, ...). Tobias * Some projects demand the compilation of "-Wall -Werror" ** gfortran provides the option -fall-intrinsics which enables all vendor intrinsics and intrinsics of newer standards with, e.g., -std=f95. |
|
|||
|
Tobias; What would be the most strict compiler options to use for check for everything possible? is it -warn=all -fcheck=all -fall-intrinsics I am looking for the most strict options that will check for EVERYTHING, at compile time, and run time. I get little confused by all the options. Would the above do it? I thought you would know better. Which std= do you recommend to use for the most strict checking? i.e. if I want more checking done, should I use std=2008? or ? or it does not matter? thanks, --Nasser On 6/24/2012 3:47 AM, Tobias Burnus wrote: > Jos Bergervoet wrote: >> On 6/23/2012 11:07 PM, Tobias Burnus wrote: >>> Nasser M. Abbasi wrote: >>>> -------------------------- >>>> integer, parameter:: N=3 >>>> real(dp) :: r >>>> r = (N-1)/N >>>> >>>>> gfortran -fcheck=all -Wall t7.f90 >>>>> ./a.out >>>> 0.0000000000000000 >>>> >>>> Because one 'forgot' to make 'one' of the variables >>>> in that line real. The compiler did not even warn about it. >>> >>> Unfortunately, there is too many valid code to warn in cases like you >>> had. Such code has typically the form: >>> >>> complex = real ! esp. "0.0" >>> real = integer ! esp. "0" or some loop variable >> >> No, that's widening and is the opposite of what the >> complaint here is about! > > Well, in the original code, the assignment of an integer to a real is > also a kind of widening (even if there can be precision loss for large > integers). At least there are many valid codes, where one has > > real_var = integer_index_var > > Additionally, widening is also not always correct. Think of the famous > > double precision :: x > x = sqrt(2.0) > > The code is perfectly valid, however, the programmer probably intended > to write "sqrt(2.0d0)". > > >> A similar problem with complex does ,however, exist. A list of them: >> >> integer :: i >> real :: x >> complex :: c = (1.0, 2.0) >> >> x = c ! <-- should give error/warning !!! >> i = x ! <-- should give error/warning !!! >> x = 1/2 ! <-- should give error, warning or 0.5 > > There shouldn't be an error as Fortran allows it. However, gfortran > warns for the first two with -Wconversion / -Wall. > > As written before, "x = 1" or similar occurs too often in valid code to > warn with -Wall. (gfortran warns for it with -Wconversion-extra.) > > One could start a complicated heuristic, which takes into account what > exactly is written on the right-hand side, e.g. warning if the RHS > contains an integer division while the LHS has is a floating-point > variable. But that starts to get rather complicated and is orthogonal to > the way Fortran evaluates expressions: Namely, first evaluating the RHS > without taking the LHS into account, before assigning to the LHS. > > > (Side remark: Due to popular demand, gfortran supports > real = z'FFFFF' > where the RHS is evaluated as real(z'FFFFFF'), though gfortran falls > back to regard the BOZ as integer as soon as the BOZ is in any kind of > expression. Other compilers use a more complicated heuristics. > Fortunately, Fortran 2003 allows to have BOZ literals as arguments to > REAL, INT and CMPLX, which solves this issue.) > > > * * * > > I want to additionally note that giving the proper warning/error > messages is not that simple if a compiler wants to support everything > from Fortran 66/77 (with legacy extensions) to Fortran 2008 code, where > the latter could be also F66 code with few F2008 features. > > Mere users usually prefer no errors/warnings and even if the compiler > points out a real problem, they rather like to have it swept under the > carpet rather than to think about solving the issue. > > Developers of modern code would like to have strict checking and > extensive warnings (but without false positives!),* but also be able to > sweep some issues under the carpet, e.g. by getting away when using a > certain vendor extension - or construct from a newer version of the > standard.** > > The whole is complicated by the fact that most compiler users do not > read the manual. The maximal one can expect that they know about -O<n> > for optimization, "-g" for debugging symbols, some way of turning on the > standard diagnostic (e.g. -std=f2003 or -stand f03 or ...), some > default-set of warnings (-Wall, -warn all, -w=all, ...) and turning > bound/other run-time checks on (-fcheck=all, -check all, -C, ...). > > Tobias > > * Some projects demand the compilation of "-Wall -Werror" > > ** gfortran provides the option -fall-intrinsics which enables all > vendor intrinsics and intrinsics of newer standards with, e.g., -std=f95. > |
|
|||
|
Nasser M. Abbasi wrote:
> What would be the most strict compiler options to use for > check for everything possible? > > is it > -warn=all -fcheck=all -fall-intrinsics -fcheck=all turns on all run-time checks (Including "array-temps" whose output is only an aid to performance tuning.) -std=f95/f2003/f2008/f2008ts - reject vendor extensions (or newer language features) -fall-intrinsics does not really fall into this list. If you use -std=f95/f2003/f2008 it actually the opposite: Instead of warning that an intrinsic is not in the selected standard, it silently accepts vendor intrinsics and intrinsics which are only in newer standards. Regarding warnings: I think the following set encompasses all Fortran warnings; there might be some more middle-end warnings, I haven't checked - but -Wall/-Wextra should also cover most of those warnings. (* = new in GCC 4.8, ** = before enabled by default.) -Wall -Wextra -Wconversion-extra -Wc-binding-type*,** -Wcharacter-truncation -Wimplicit-interface -Wsurprising -Wunderflow (Additionally, there are the warnings which help with performance tuning: -Warray-temporaries -Wrealloc-lhs* and -Wrealloc-lhs-all*) -fimplicit-none - forces IMPLICIT NONE, which helps to find bugs if one has forgotten to specify it manually. (-pedantic can also give some diagnostic) For a description of the flags, see the manual; e.g. http://gcc.gnu.org/onlinedocs/gfortr...n-Summary.html - and for general GCC flags see also http://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html > Which std= do you recommend to use > for the most strict checking? i.e. if I want more checking > done, should I use std=2008? or ? or it does not matter? Well, the "strictest" is -std=f95 as it also rejects the features which were added in Fortran 2003 and Fortran 2008. However, the question is more which Fortran standard you want to use. Fortran 95 is most widely supported but certain features of Fortran 2003 and Fortran 2008 are very useful, but are available in fewer compilers. I think the best choice for wide compatibility would be Fortran 95 plus Technical Report (TR) 15581, which added allocatable components/dummy arguments. As gfortran does not have such a flag, -std=f2003 has to be used in that case. But also in general, -std=f2003 is probably a good choice as Fortran 2003 has many useful features, many of which have been implemented in several compilers. Using -std=f2008 (or with GCC 4.8 even -std=f2008ts) can make sense as Fortran 2008 added some nice features. Though, the number of compilers which support parts of Fortran 2008 is even lower. (-std=f2008ts will allow the additions of the post-F2008 Technical Specifications (TS), namely TS29113 on Further Interoperability of Fortran with C and the upcoming coarray TS. Parts of TS29113 are already implemented in gfortran - and will be used internally for the implementation of Fortran 2003's FINAL subroutines.) Tobias |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|