How about a warning??

How about a warning??

How is it even possible?? Yesterday I had nothing to do at work, so I decided to move the entire project from VS 2008 Pro + IVF10 to Code::Blocks 12.11 with gfortran 4.7 or something, just to play with new tools and pass some time. I was shocked to find that gfortran found THOUSANDS of errors, either real compiler errors or simple warnings that are simple warnings because of Fortran's archaic rules but are actually subtle bugs which I would NEVER find using IVF. One example above all (please disregard the code itself, it's legacy and horrible and I didn't even read it):

Not even a warning? What is ''C ?? Ok, let's see gfortran:

How could this slip through? I compiled with IVF using -Wall (or its equivalent)!!!

Pls don't say "it's the old version, IVF Composer 2013 works fine", this product was paid for and 2008 is just a few years ago!!

Other examples of mistakes not caught:

FORMAT('Error at line number ', I) instead of FORMAT('Error at line number ', I3)

gfortran's message: "error: you must give a non-null width for the number in the format statement" (or something like that)!! There were hundreds of these typos, and not a single word from IVF!

And above all: not a single warning about the use of uninitialized variables! How many times have I had to debug at runtime this (awful) legacy code because a parameter was moved from an include file to another, leaving an implicitly decleared variable uninitialized in every subroutine that includes the old include file?? Wow...really shocked.

Am I missing anything? Because I used the option to warn for everything...but the best it can do is warn against implicitly declared variables, HOW USEFUL!

31 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

You seem to be complaining about extensions supported by Intel Fortran but not gfortran. If you compile with standards checking enabled, you'll get warnings. The code you showed is perfectly valid in Intel Fortran.  For example:

t.f(6): warning #6182: Fortran 2003 does not allow this edit descriptor.   [I]
101   FORMAT ('Error at line number', I)
^

I do note that we don't give a standards warning for the ''C syntax, and that's a bug I will report. This is a "C character literal", one in which backslash escape sequences are recognized and a trailing NUL is added.

Steve - Intel Developer Support

Andrea B.: Pardon me, but you may be in for a few more shocks.

If the code ran "correctly" on an old system (say, an SDS9300 or a Univac 1101), it did depend on vendor extensions to standard Fortran to run -- you just established that the code does not build without errors under standard Fortran rules. The interpretations of extensions that are accepted by System X and System Y may be different. Unless you take charge of these extensions, how are you ever going to trust the results, given that System X is now a heap of rust and System Y does not claim to duplicate the functionality of System X? 

If you found a "real compiler error", please give us an example. Something gfortran doesn't like doesn't, on its own, count. I will agree that gfortran will warn you about some legal but dubious usages, and that's nice. However, most of our customers prefer not to get warnings for their existing code that does what it is supposed to do.

Steve - Intel Developer Support

Thanks to both for the swift replies.

mecej: I have established that many bugs were not found by IVF. I understand that one compiler may provide extensions that another one does not, because sadly Fortran77 was never strictly standardized, but I expected to be at least warned for the typo I listed, since they break the code in a marked manner.

I just found another one: I was passing an argument, vector VP, in a subroutine like this:

call that_subroutine([arguments], V P, [other arguments])

There was a damn space between the two letters forming the identifier, and it was all ok, for ages!! How is that possible? Extensions? Well, it looks like the actual result of using such extensions is to help concealing bugs rather than trying to make programming easier, as I would expect from a modern tool, above all in light of the horrible language that Fortran is (from the programming point of view).

Steve: ok, I didn't know about the ''C syntax (I could figure that out knowing that C++ uses such literals, but again I didn't expect an "extension" to get in my way...), but that's just one of the many bugs I found in my program.

Anyway, maybe I should blame the UI of your compiler rather than the compiler itself, meaning: how do I turn on the check you are talking about? In project settings, I go to Fortran -> Diagnostics -> Language Usage Warnings and I cannot find anything regarding standard checks (that one is in General, "Warn for non standard Fortran", but still doesn't warn about using I instead of I3) and above all, I can't find the switch to turn on warnings about uninitialized variables. That's a real source of bugs, when you couple this with implicit declaration! For example, variable IP1 must be checked, and in some of the IFs the check was performed on IP! Someone forgot the 1...

Where is the switch?

Quote:

Andrea B. wrote:

call that_subroutine([arguments], V P, [other arguments])

There was a damn space between the two letters forming the identifier, and it was all ok, for ages!! How is that possible? Extensions?

In fixed-format Fortran, embedded spaces in keywords and variable names have no significance to the compiler. They can be used to improve readability or removed/misplaced to incorporate obfuscation.

Keep in mind that Fortran is almost as old as Cobol and, while it has evolved over the years, backward compatibility is prized and therefore we may find many features in the language that we might design differently if we were to start with a clean slate today. Although bugs are not uncommon in some old Fortran code, the bugs are much easier to detect and remove than in, say, pre K-&-R C.

Fortran 77 (or more formally, FORTRAN 77) was indeed standardized.  The code you show is not standard FORTRAN 77 - it uses extensions. I still don't see an example of a "bug" that Intel Fortran failed to warn you about. As you are finding, though, while Fortran has been standardized, probably a majority of the programs you will find out there use at least some non-standard extensions, especially when calling outside of Fortran. (Fortran 2003 added a lot of nice features to allow you to do many of these in a standard way, but they're far from ubiquitous in code.)

"Warn for non-standard Fortran" does warn for I instead of I3, as I showed. I by itself has an implied width based on the kind (size) of the integer value (7, 12 or 23). Fortran 2008 adds I0 which uses the minimum width needed to represent the value - that's nice to use.

mecej4 has already told you about insignificant blanks. Many older programs made use of this feature for "readability", though it can also be confusing. I recommend free-form source for new code as it will help catch some inadvertent errors due that fixed-form source rules would allow. See also Doctor Fortran in "Source Form Just Wants to be Free".

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

Fortran 77 (or more formally, FORTRAN 77) was indeed standardized.  The code you show is not standard FORTRAN 77 - it uses extensions. I still don't see an example of a "bug" that Intel Fortran failed to warn you about. As you are finding, though, while Fortran has been standardized, probably a majority of the programs you will find out there use at least some non-standard extensions, especially when calling outside of Fortran. (Fortran 2003 added a lot of nice features to allow you to do many of these in a standard way, but they're far from ubiquitous in code.)

"Warn for non-standard Fortran" does warn for I instead of I3, as I showed. I by itself has an implied width based on the kind (size) of the integer value (7, 12 or 23). Fortran 2008 adds I0 which uses the minimum width needed to represent the value - that's nice to use.

mecej4 has already told you about insignificant blanks. Many older programs made use of this feature for "readability", though it can also be confusing. I recommend free-form source for new code as it will help catch some inadvertent errors due that fixed-form source rules would allow. See also Doctor Fortran in "Source Form Just Wants to be Free".

Ok thanks. New code is being written in C++, I'll stay far from FORTRAN as much as I can.

What I realized with your comment is: what I thought I knew about standard FORTRAN is actually not standard. I probably have never learned the standard rules and have been using extensions all the time without knowing (and at this point, never will) since I've always used this language in different environments (CVF, VS + IVF). Therefore, I'll just stop trying to understand why a given compiler does or does not warn about a particular feature, I'll just take it. I'm at peace now :D

Quote:

Andrea B. wrote:

Quote:

Ok thanks. New code is being written in C++, I'll stay far from FORTRAN as much as I can.

My condolances - numerous studies have shown that productivity in C++ is very low. You'd be better off with Fortran.

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

- numerous studies have shown that productivity in C++ is very low. You'd be better off with Fortran.

Hi Steve,

Very interesting you should say this.  I've heard the same as well; in fact, I recall reading a report somewhere that some major US agency (NOAA?) decided to switch back to Fortran following several years of effort to develop large programs in C++ and if I remember correctly, this was after millions of dollars of expense and significant productivity loss.  But I am now unable to locate this reference or determine which agency it was.

Re: your comment above, would you have any references (reports/articles, websites, white papers, etc.) for the numerous studies you mention.

This will be very useful for ongoing discussions with management where I work.

Thank you much,

I found http://www.academia.edu/886481/An_empirical_study_of_software_developmen... , though it compared C++ to C. However, the conclusions would also relate to Fortran as a "procedural language". But I can find some contrasting data points, such as http://www.drdobbs.com/jvm/the-comparative-productivity-of-programm/2400... . I was recalling the same report you mentioned, but I can't find it right now either.

Our own experience is that C++ is ok as long as you mainly stick to C. Back when I was at DEC we had more than one project go "off the rails" when developers were asked to use C++ in all its glory, but I am sure there are counter-examples everywhere.

Steve - Intel Developer Support

Of necessity, these articles that undertake a comparison of two languages do not account for an important consideration that an individual making the choice must face: different levels of expertise and experience in the two languages. It is hardly surprising when, for example, a proficient C++/novice Fortran user has occasion to compile and use Fortran code written by someone else, and blames Fortran for being such a horrid language.

That's certainly my case. I know C++ quite well (and because of this, I know I can't say I know the language VERY well) and I'm productive. In FORTRAN I'm not (also because the project is managed by an idiot that wants to stick to the 77 standard instead of taking advantage of the new features). So yeah, thanks for the condolences.

About that absurd sentence "C++ is ok as long as you stick to C", productivity is all about astraction. Using C++ as it were C means not to take advantage of all the abstractions it offers, which greatly speed up programming, make it safer (no pointers floating around and causing memory leaks, for example), type safe, and way easier to maintain. The sentence as it is is pure contradiction, it should be rephrased as: "if you're an old school procedural programmer who already has a strong background with C and Fotran, you'll find using C++ in C-style way easier because you already know how to use it", and that's it. Who in his right mind would ever use char*, strcmp and other C style constructs instead of std::string and the STL? Someone who doesn't know about the STL, I suppose.

By the way, 99% of the bugs (warnings, let's say) found by gfortran would just not be possible in C++ because of the type system.

P.S.: check out the new C++11 standard

Andrea, I am still looking for an example of a "real bug" in the code that gfortran found but Intel Fortran didn't.

I certainly agree that familiarization with a language is the #1 attribute to be considered when choosing. I don't for a moment think Fortran is best for every application and every programmer. I've said so on many occasions. Personally, I'm not very skilled in C++ (better in C), but I do find the syntax added to C++ over the years to be, um, challenging.

It would all be better in Ada....

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

Andrea, I am still looking for an example of a "real bug" in the code that gfortran found but Intel Fortran didn't.

I certainly agree that familiarization with a language is the #1 attribute to be considered when choosing. I don't for a moment think Fortran is best for every application and every programmer. I've said so on many occasions. Personally, I'm not very skilled in C++ (better in C), but I do find the syntax added to C++ over the years to be, um, challenging.

It would all be better in Ada....

I see your reply to my post but I don't see my post yet. Why do all posts have to go through screening before being published?? Bah.

Anyway, I already wrote about a real bug in one of my first posts:

      SUBROUTINE CHCV05(Z,IP1,IP2,IC,*)

    IMPLICIT DOUBLE PRECISION (A-H,O-Z)
C     
    INCLUDE 'GSP1.INC'
    INCLUDE 'GS1.INC'
C
      CHARACTER*6 FNAME
      PARAMETER (FNAME = 'CHCV05')
C
    LOGICAL Z
C
      DIMENSION IC(NDX)
C
      CALL GSMNIT(1,FNAME)
C
      IF(Z) THEN
        IF(IP1.EQ.0) THEN
          GOTO 90      
        ELSEIF(IP1.EQ.1) THEN
          IF(IC(JD1 + 4).LT.0) GOTO 90
        ELSEIF(IP.EQ.2) THEN
          IF(IC(JD1 + 3).NE.0) GOTO 90
        ELSEIF(IP.EQ.3) THEN
          IF(IC(JD + 1).NE.-1) GOTO 90
        ELSEIF((IP.EQ.4).OR.(IP.EQ.5).OR.(IP.EQ.6).OR.(IP.EQ.7).OR.(IP
     #  .EQ.8).OR.(IP.EQ.9).OR.(IP.EQ.10)) THEN
          GOTO 90
        ENDIF
      ENDIF
C
      CALL GSMNIT(2,FNAME)  
C
      RETURN
C
   90 RETURN 1
C
      END

See? Because of implicit typing, the typo which makes IP1 become IP goes undetected because IP will be silently instantiated with a value of 0 (or random garbage? For us it's 0 because we use /Qsave). No word from your compiler, a warning from gfortran thanks to -Wuninitialized.

And that's a bug in my code; digging further, I've found out a bug real bug in the VS plugin: the diagnostics section shows "Check routine interfaces: yes", but in the .vcproj file the option is not there!! See the screenshot:

In Beyond Compare, in the background, you see on the left the freshly created project, called Clean GS, where I have put all the .FOR files that I've fixed thanks to gfortran, because I wanna make sure they still compile in IVF; on the left the old one, called GS. As you see, the UI is from the GS, and is showing that /warn:intefaces is on, but in the .vcproj file there is no such switch, and Beyond Compare highlights this difference!

The project file has somehow gotten corrupted...

Please post the include files GSP1.INC and GS1.INC so that we may run some static analysis tools on your source code for subroutine CHCV05.

Intel Fortran does have run-time uninitialized variable checking, but I don't know if it would have caught this. The Static Analysis feature of Intel Fortran Studio XE would have. I agree that compile-time uninitialized variable checking is good. It remains something we want to add.

The options are not necessarily in the same order in the project file. I see WarnInterfaces="true" in the right-side screenshot, which is the project for which you show the properties. The one on the left looks a bit odd and I'd like to see the actual .vfproj file.

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

Intel Fortran does have run-time uninitialized variable checking, but I don't know if it would have caught this. The Static Analysis feature of Intel Fortran Studio XE would have. I agree that compile-time uninitialized variable checking is good. It remains something we want to add.

The options are not necessarily in the same order in the project file. I see WarnInterfaces="true" in the right-side screenshot, which is the project for which you show the properties. The one on the left looks a bit odd and I'd like to see the actual .vfproj file.

Well...of course I know that the options are not in the same order...and the highlighted part is the only difference for that line. But if that's not enough, I will show you the compile error in Clean GS, due to passing a double to a subroutine taking an int, that is not given in GS.

I'll post the INC files in a week, I'm officially on vacation now; although I don't see what could be wrong with a bunch of integer parameters, with no common. That IP is just an obvious typo.

With generated interface checking, compile order matters. The called routine has to be compiled before the caller (or has to be in the same source file.)

Steve - Intel Developer Support

Hello again.

@mecej: for the static analysis, as requested, GSP1.INC contains the following:

      INTEGER NCX
      INTEGER NCXT
      INTEGER NPX
      INTEGER NCVX
      INTEGER NCV$X
      INTEGER NIX
      INTEGER NOX
      INTEGER NRIC
      INTEGER NISX
      INTEGER NOSX
      INTEGER NTD
      INTEGER NDX
      INTEGER NEX
      INTEGER NEN
      INTEGER NNX
      INTEGER NPRX
      INTEGER NGASX
      INTEGER NSTMAX
      INTEGER ISTP
      INTEGER NCTMAX
      INTEGER NPTMAX

      PARAMETER (NCX    = 104)
      PARAMETER (NCXT   = 4)
      PARAMETER (NPX    = 160)
      PARAMETER (NCVX   = 50)
      PARAMETER (NCV$X  = 30)
      PARAMETER (NIX    = 7)
      PARAMETER (NOX    = 10)
      PARAMETER (NRIC   = 75)
      PARAMETER (NISX   = 25)
      PARAMETER (NOSX   = 25)
      PARAMETER (NTD    = 80)
      PARAMETER (NDX    = 1300)
      PARAMETER (NEX    = 50)
      PARAMETER (NEN    = 15)
      PARAMETER (NNX    = 25)
      PARAMETER (NPRX   = 10)
      PARAMETER (NGASX  = 2)
      PARAMETER (NSTMAX = 10)
      PARAMETER (ISTP   = 60)
      PARAMETER (NCTMAX = 4)
      PARAMETER (NPTMAX = 110)

I removed INCLUDE 'GS1.INC' from subroutine CHCV05, it was an old leftover. Thanks for putting some time into this :)

@Steve: I put in attachment the 2 project files from my old and new solutions (GS and CleanGS, respectively). And here is what CleanGS does tell me, since "check routine interfaces" actually works:

Attachments: 

AttachmentSize
Downloadapplication/zip gs-vs-cleangs.zip3.16 KB

Andrea, would you please attach a zip of the buildlog.htm after a rebuild of both projects? The project files look fine to me - both have the option enabled. It could simply be an order of compilation issue.

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

Andrea, would you please attach a zip of the buildlog.htm after a rebuild of both projects? The project files look fine to me - both have the option enabled. It could simply be an order of compilation issue.

Sure, but let me know if any sensible info about my code may contained in that file. If so, I'll send you the file privetely, otherwise I'll just attach it here.

Thanks.

There's nothing about your code in the build log other than the names of the source files, unless there are error messages that quote source lines. You're welcome to send it to me privately if that's a concern.

Steve - Intel Developer Support

Actually, there's still a lot to clean up in CleanGS, stuff that gfortran didn't catch because despite many advantages over IVF, there's no option to check routine interfaces :) so I am not able yet to compile the project with this option turned on. I am starting to doubt I will ever be because there are so many mistakes, or simple bad parts of code, in this awful spaghetti code...

If I make it, I'll finally post the two buildlog files. Fingers crossed.

Quote:

Steve Lionel (Intel) wrote:

There's nothing about your code in the build log other than the names of the source files, unless there are error messages that quote source lines. You're welcome to send it to me privately if that's a concern.

Edit: will put the correct ones shortly.

Quote:

Steve Lionel (Intel) wrote:

There's nothing about your code in the build log other than the names of the source files, unless there are error messages that quote source lines. You're welcome to send it to me privately if that's a concern.

Here it is. Note the link error at the end of GS build, it is resolved just by launching the program with F5. No clue why.

Edit: found out why it wasn't working: /gen-interfaces must be on for /warn:interfaces to work...is this how it's supposed to work (common sense would suggest so)?

Attachments: 

AttachmentSize
Downloadapplication/zip buildlogs.zip9.25 KB

I had not realized you were using compiler version 10.1!  I see now you said that in the original post but I missed it. Yes, in that version you need both /gen-interface and /warn:interface to get the warnings. In more recent versions (11.1 and later, I think), /warn:interface implies /gen-interface so you don't need the latter.

Why are you using a compiler from more than four years ago?

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

I had not realized you were using compiler version 10.1!  I see now you said that in the original post but I missed it. Yes, in that version you need both /gen-interface and /warn:interface to get the warnings. In more recent versions (11.1 and later, I think), /warn:interface implies /gen-interface so you don't need the latter.

Why are you using a compiler from more than four years ago?

Because this is what they have here, simple! And after all, I'm using a compiler from 5 years ago for a language from 36 years ago, I think it's still fair ;)

Thanks for the time, as always you're extremely helpful :)

Andrea

I don't think it is fair to describe this as "a language from 36 years ago." In some circles, the need for language evolution is accomplished by abandoning old languages and inventing new ones, resulting in the hundreds of possibilities we have today. In the Fortran community it is realized by advancing the language in a very methodical and controlled with great concern for backwards compatibility and longevity. I prever the latter approach.

Quote:

Steve Lionel (Intel) wrote:

I by itself has an implied width based on the kind (size) of the integer value (7, 12 or 23). Fortran 2008 adds I0 which uses the minimum width needed to represent the value - that's nice to use.

Steve,

I was reading back through your posts on this topic. I am not familiar with the "I" format. When was this introduced? Has Fortran 2008 modified the way I0 was defined in Fortran 90.
I wish there was an option for I0(+1) to provide a leading space. Has this been introduced in 03 or 08 ?
I also find there is a some variability between compilers in the precision provided by *) format, so does the recent standard provide more precision definition for the "I" (or "F" if it exists) format ?

John

I without a width is non-standard. It is an extension which dates back to DEC compilers in the early 1970s (pre-F77) and is sort of a poor-man's substitute for list-directed I/O. There are default widths for other data types supported - see the documentation - but I don't recommend using these in new code.

I0 has not changed in meaning since it was introduced. But since it always provides minimum width with no blanks, you can always put in the leading blank yourself with 1X.

Variability with list-directed formatting is exactly the way the standard defines it. Indeed, the standard has given implementations even more latitude in recent releases, such as allowing use of G0 (we now do this if /standard-semantics is enabled.)

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today