On Nov 30, 2004, at 1:40 AM, Bertrand Meltz wrote: > I often use this piece of program in my codes. > Some compilers insist that this is a recursive library call. > Is it really? [code elided] Yes. This is *EXACTLY* the kind of thing that the recursive I/O restriction is about. Speaking sloppily (if you wanted the formal version, I could quote the standard's words, but perhaps my sloppy words will provide a different perspective - or maybe not)... You are in the process of doing I/O (namely the print *) when the function is called. That function then does I/O itself. > It does not seem to me to be "more recursive" than > a = MAX( b, MAX( c, d)) > which always works. which is besides the point. The standard doesn't restrict that; it does explicitly restrict recursive I/O. One could go on for a long time with reasons. I'll just briefly mention a few. 1. Getting a bit historical, but many compilers used to have I/O libraries that couldn't handle this without a complete rewrite (so I am told). I/O libraries are big and complicated and thus a big deal to rewrite. Max isn't. My understanding is that by now, most I/O libraries have already bitten this particular bullet, but that didn't used to be true. 2. There are cases where it is hard to even define what recursive I/O would mean. That's particularly so when the recursive I/O is to the same unit. This particular case doesn't have that problem, but realize that there are many, many restrictions in the standard that are broader than absolutely necessary because it would add complication (sometimes very large amounts) to precisely delimit the problem cases. In the case of recursive I/O, it has been decided that a few cases (including this one) are safe, common, and useful enough, and easy enough to describe, so that the boundary of the prohibition was moved in f2003. There is still a prohibition, but its boundary moved past this case. In particular, internal I/O is allowed. 3. The situation with max has a fundamental difference that you probably don't appreciate because your I/O statement is so simple. I/O can get really complicated. The standard has to cover all the cases. And as mentioned in point 2, it is sometimes messy to draw a precise boundary betweeen safe cases and problem ones. In particular, the arguments to a procedure are in principle (and usually in fact) evaluated *BEFORE* calling the procedure. Thus your example with max isn't really recursive; there aren't 2 "copies" of MAX running at the same time. The "innermost" MAX invocation is completed (at least in principle - optimizers can play tricks) before the outermost one is called. But I/O statements can't always work that way. Yours is simple enough that it can. But in more complicated cases, you have to actually do some of the I/O for early items in the list before you can evaluate later items. Thus I/O cannot be described in all cases by saying to first evaluate the I/O list and then do the I/O. You have to first start the I/O and then work through the I/O list. This means that there are 2 "copies" of the I/O runtimes active at the same time if there is any I/O in functions in the original I/O list. A a final reminder, mentioned above, but worth highlighting. This code is ok in f2003, just not in f95 or earlier. (Though I'm sure some f95 compilers allow it as an extension... perhaps not even intentionally, but just that it works). -- Richard Maine | Good judgment comes from experience; [log in to unmask] | experience comes from bad judgment. | -- Mark Twain