468,170 Members | 2,081 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,170 developers. It's quick & easy.

Extent of the "as-if" rule

Hi all,
In a discussion with Tak-Shing Chan the question came up whether the
as-if rule can cover I/O functions. Basically, he maintains it can, and
I think it doesn't.

Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
in main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?

I'd welcome a reference from the standard.

Best regards,

Sidney

Nov 14 '05 #1
145 5235
Sidney Cadot wrote:
Hi all,
In a discussion with Tak-Shing Chan the question came up whether the
as-if rule can cover I/O functions. Basically, he maintains it can, and
I think it doesn't.

Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
in main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?

I'd welcome a reference from the standard.

Best regards,

Sidney


I'll take a stab at this...

Since fopen() is a function (15.2), it may therefore have side effects.
Optimizing it away would therefore be an error.

Perhaps the OS it's running on starts up a pot of coffee if someone
opens the 'somefile' file for reading, and that's the intended effect.

/J
Nov 14 '05 #2
Greetings.

In article <bu*********@news.tudelft.nl>, Sidney Cadot wrote:
Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
in main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?

I'd welcome a reference from the standard.


I don't know what the standard says, but from an implementation point of
view it might make sense not to optimize the fopen() away. Many file
systems maintain a "last accessed" timestamp for files; therefore, the
seemingly useless fopen() does indeed modify the environment.

Regards,
Tristan

--
_
_V.-o Tristan Miller [en,(fr,de,ia)] >< Space is limited
/ |`-' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= <> In a haiku, so it's hard
(7_\\ http://www.nothingisreal.com/ >< To finish what you
Nov 14 '05 #3
In <40********@news.wineasy.se> Johan Lindh <jo***@linkdata.getridofthis.se> writes:
Sidney Cadot wrote:
Hi all,
In a discussion with Tak-Shing Chan the question came up whether the
as-if rule can cover I/O functions. Basically, he maintains it can, and
I think it doesn't.
The as-if rule basically says that any optimisation/pessimisation is
allowed, as long as the *specified* output of the program is not affected.
Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
int main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?
Yes, because both programs generate the same output, according to the
description of the abstract machine. Opening a file in read mode and
closing it (if the opening succeeded) does not generate any output.
I'd welcome a reference from the standard.


I'll take a stab at this...

Since fopen() is a function (15.2), it may therefore have side effects.
Optimizing it away would therefore be an error.

Perhaps the OS it's running on starts up a pot of coffee if someone
opens the 'somefile' file for reading, and that's the intended effect.


The only *relevant* side effects of fopen are those specified in the C
standard.

Here is the standard reference:

5.1.2.3 Program execution

1 The semantic descriptions in this International Standard describe
the behavior of an abstract machine in which issues of optimization
are irrelevant.

2 Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations
are all side effects,11) which are changes in the state of the
execution environment. Evaluation of an expression may produce
side effects. At certain specified points in the execution
sequence called sequence points, all side effects of previous
evaluations shall be complete and no side effects of subsequent
evaluations shall have taken place. (A summary of the sequence
points is given in annex C.)

3 In the abstract machine, all expressions are evaluated as
specified by the semantics. An actual implementation need not
evaluate part of an expression if it can deduce that its value is
not used and that no needed side effects are produced (including
any caused by calling a function or accessing a volatile object).

Opening a file in read mode doesn't modify the file, therefore it doesn't
count as a side effect, in the context of the C standard.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #4

Cross-posted to comp.std.c from a discussion in comp.lang.c; feedback
welcomed.
Dan Pop wrote:
In <40********@news.wineasy.se> Johan Lindh <jo***@linkdata.getridofthis.se> writes:

Sidney Cadot wrote:

Hi all,
In a discussion with Tak-Shing Chan the question came up whether the
as-if rule can cover I/O functions. Basically, he maintains it can, and
I think it doesn't.

The as-if rule basically says that any optimisation/pessimisation is
allowed, as long as the *specified* output of the program is not affected.

Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
int main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?

Yes, because both programs generate the same output, according to the
description of the abstract machine. Opening a file in read mode and
closing it (if the opening succeeded) does not generate any output.

I'd welcome a reference from the standard.


I'll take a stab at this...

Since fopen() is a function (15.2), it may therefore have side effects.
Optimizing it away would therefore be an error.

Perhaps the OS it's running on starts up a pot of coffee if someone
opens the 'somefile' file for reading, and that's the intended effect.

The only *relevant* side effects of fopen are those specified in the C
standard.

Here is the standard reference:

5.1.2.3 Program execution

1 The semantic descriptions in this International Standard describe
the behavior of an abstract machine in which issues of optimization
are irrelevant.

2 Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations
are all side effects,11) which are changes in the state of the
execution environment. Evaluation of an expression may produce
side effects. At certain specified points in the execution
sequence called sequence points, all side effects of previous
evaluations shall be complete and no side effects of subsequent
evaluations shall have taken place. (A summary of the sequence
points is given in annex C.)

3 In the abstract machine, all expressions are evaluated as
specified by the semantics. An actual implementation need not
evaluate part of an expression if it can deduce that its value is
not used and that no needed side effects are produced (including
any caused by calling a function or accessing a volatile object).

Opening a file in read mode doesn't modify the file, therefore it doesn't
count as a side effect, in the context of the C standard.


.... But that just dismisses one of the possible 'side effects' admitted
by the standard.

Does a fopen(name, "rb") count as 'calling a function that does any of
those operations' ? I think it does; it /has/, at some point, to
interact with the abstract machine's environment, which can only be done
via volatile objects or modifying an object, eventually, somewhere
down the line.

Anyway, we can pick on words (and that's valuable) but if anything, this
shows that the enumeration of 'side effects' as given in the standard
is not exhaustive. Clearly, opening a file (even for reading) interacts
with the outside world, e.g. on unix systems it updates the 'last
accessed' date as pointed out. This is not unambiguously covered by the
standard; if upon literal reading we were to conclude that it isn't
properly covered - well, then the standard needs to be mended on the
next occasion.

Best regards,

Sidney
Nov 14 '05 #5
On 19 Jan 2004 16:13:33 GMT, Da*****@cern.ch (Dan Pop) wrote in
comp.lang.c:
In <40********@news.wineasy.se> Johan Lindh <jo***@linkdata.getridofthis.se> writes:
Sidney Cadot wrote:
Hi all,
In a discussion with Tak-Shing Chan the question came up whether the
as-if rule can cover I/O functions. Basically, he maintains it can, and
I think it doesn't.
The as-if rule basically says that any optimisation/pessimisation is
allowed, as long as the *specified* output of the program is not affected.
Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
int main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?
Yes, because both programs generate the same output, according to the
description of the abstract machine. Opening a file in read mode and
closing it (if the opening succeeded) does not generate any output.
I'd welcome a reference from the standard.


I'll take a stab at this...

Since fopen() is a function (15.2), it may therefore have side effects.
Optimizing it away would therefore be an error.

Perhaps the OS it's running on starts up a pot of coffee if someone
opens the 'somefile' file for reading, and that's the intended effect.


The only *relevant* side effects of fopen are those specified in the C
standard.

Here is the standard reference:

5.1.2.3 Program execution

1 The semantic descriptions in this International Standard describe
the behavior of an abstract machine in which issues of optimization
are irrelevant.

2 Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations
are all side effects,11) which are changes in the state of the
execution environment. Evaluation of an expression may produce
side effects. At certain specified points in the execution
sequence called sequence points, all side effects of previous
evaluations shall be complete and no side effects of subsequent
evaluations shall have taken place. (A summary of the sequence
points is given in annex C.)

3 In the abstract machine, all expressions are evaluated as
specified by the semantics. An actual implementation need not
evaluate part of an expression if it can deduce that its value is
not used and that no needed side effects are produced (including
any caused by calling a function or accessing a volatile object).

Opening a file in read mode doesn't modify the file, therefore it doesn't
count as a side effect, in the context of the C standard.


Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.

It would not be acceptable on a Win32 system, and quite possible other
systems. Win32 keeps multiple time values for files in the file
system, one of which is the last accessed time. An open of an
existing file followed by a close without reading or writing will
modify the file system's last access time, which does modify the file
even though it does not change the contents.

[also cross-posted to comp.std.c]

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #6
Jack Klein <ja*******@spamcop.net> writes:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


Most Unix-like kernel, including Linux, also maintain "last
accessed" times. I don't know why you think they don't.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 14 '05 #7
On Mon, 19 Jan 2004 20:20:42 -0800, Ben Pfaff <bl*@cs.stanford.edu>
wrote in comp.std.c:
Jack Klein <ja*******@spamcop.net> writes:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


Most Unix-like kernel, including Linux, also maintain "last
accessed" times. I don't know why you think they don't.


Doh! I probably knew that, although I haven't had anything running
Linux in quite a while. It's time of creation that they don't keep
separately, right?

In any case the real question is:

Given:

-Compilers that generate executables for platforms A and B

-Platform A does not change the externally visible state of its file
system in any way when an existing file is opened and closed with no
actual access in between.

-Platform B does change the externally visible state of its file
system in some way (e.g., updating a last accessed time stamp field
associated with the file) under the same circumstances.

-The following program:

#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

....where the parameters passed to fopen() are such that the call
succeeds.

Then does it follow:

-A compiler for platform A may omit the fopen() call under the as-if
rule

-A compiler for platform B may not omit the fopen() call

....even though the output of the program itself is the same in either
case.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #8
Jack Klein wrote:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


But that is *not* the way that Unix (POSIX) works!
Opening a file *does* have side effects in the environment.

Nov 14 '05 #9
Jack Klein wrote:
Then does it follow:
-A compiler for platform A may omit the fopen() call under the as-if
rule
-A compiler for platform B may not omit the fopen() call
...even though the output of the program itself is the same in either
case.


The question is whether there is any way, other than timing,
code size, and other aspects deemed "inessential", to detect
whether the code actually performs the call. In a way, this
is all a waste of time, because no compiler that I know of
would optimize away a call to fopen(). Some *would* optimize
away pointless calls to strcmp() etc., in contexts where they
know that a standard library function is involved (so that
its complete semantics are known) and known not to have any
observable effect in the particular case.

Is there some *real* issue lying behind this topic, or is it
just a matter of pedanticism?

Nov 14 '05 #10
>Jack Klein <ja*******@spamcop.net> writes:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.

In article <87************@pfaff.stanford.edu>,
Ben Pfaff <bl*@cs.stanford.edu> wrote:Most Unix-like kernel, including Linux, also maintain "last
accessed" times. I don't know why you think they don't.


Moreover, if the file name corresponds to a fifo or named-pipe,
simply opening the file for reading can have an effect. In
particular, opening a fifo for reading will unblock a process
that is suspended in an attempt to write to that fifo:

$ mkfifo foo
$ echo hello > foo &
$ jobs
[1] 18389 echo hello >foo
$ echo zog < foo &
$ zog
jobs
[1] 18389 Exit 0 echo hello >foo
[2] 18390 Exit 0 echo zog <foo
$

If you do this in the opposite order, the attempt to read from the
fifo before there are any writers causes the reading program to
hang until someone opens the fifo for writing. Either way it is
obvious that something has happened, even though it is outside the
limited domain of portable C programming.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #11
In article <87************@pfaff.stanford.edu>,
Ben Pfaff <bl*@cs.stanford.edu> wrote:
Jack Klein <ja*******@spamcop.net> writes:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


Most Unix-like kernel, including Linux, also maintain "last
accessed" times. I don't know why you think they don't.


But it may only be updated if you actually read something from the file;
the act of opening the file in read mode might not update it (consider a
file on an NFS server -- there's nothing in NFS that corresponds to
open() or close(), the server only sees the directory lookup and the
read/write operations).

--
Barry Margolin, ba****@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Nov 14 '05 #12
"Douglas A. Gwyn" wrote:
Jack Klein wrote:
Then does it follow:
-A compiler for platform A may omit the fopen() call under
the as-if rule
-A compiler for platform B may not omit the fopen() call
...even though the output of the program itself is the same in
either case.


The question is whether there is any way, other than timing,
code size, and other aspects deemed "inessential", to detect
whether the code actually performs the call. In a way, this
is all a waste of time, because no compiler that I know of
would optimize away a call to fopen(). Some *would* optimize
away pointless calls to strcmp() etc., in contexts where they
know that a standard library function is involved (so that
its complete semantics are known) and known not to have any
observable effect in the particular case.

Is there some *real* issue lying behind this topic, or is it
just a matter of pedanticism?


I think it is purely pedantic. At any rate there is no telling
what the act of opening a file involves, regardless of system. I
have built systems where the act of opening a particular named
file did some major re-arrangement of the entire i/o system, and
the act of closing that file put it back. This kept the
application proper coding standard and restricted the magic to
file system drivers.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #13
in comp.std.c i read:
On 19 Jan 2004 16:13:33 GMT, Da*****@cern.ch (Dan Pop) wrote in
comp.lang.c:

The only *relevant* side effects of fopen are those specified in the C
standard. Opening a file in read mode doesn't modify the file, therefore it doesn't
count as a side effect, in the context of the C standard.


Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


actually unices typically do record the time a file was opened. dan might
argue that by itself that isn't sufficient, and in some ways i agree, but
there remains a flaw: there's no way to know whether the FILE object
contains a volatile member or would call the environment since it's
implementation defined.

--
a signature
Nov 14 '05 #14
Douglas A. Gwyn wrote:
Jack Klein wrote:
Then does it follow:
-A compiler for platform A may omit the fopen() call under the as-if
rule
-A compiler for platform B may not omit the fopen() call
...even though the output of the program itself is the same in either
case.

The question is whether there is any way, other than timing,
code size, and other aspects deemed "inessential", to detect
whether the code actually performs the call. In a way, this
is all a waste of time, because no compiler that I know of
would optimize away a call to fopen(). Some *would* optimize
away pointless calls to strcmp() etc., in contexts where they
know that a standard library function is involved (so that
its complete semantics are known) and known not to have any
observable effect in the particular case.

Is there some *real* issue lying behind this topic, or is it
just a matter of pedanticism?


As for me, it's mostly curiosity about the standard's wording:

"Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations
are all side effects"

.... If this would just say "accessing a file" instead of
"modifying a file" the issue would not exist. I wonder if there is a
good reason this particular wording was chosen, and - if not - would
like to see it changed. There's no reason not to strive for perfection
if it is essentially free.

Another thing is that I think the standard's way of defining a "side
effect" (by enumeration of cases) is flawed. This is a bit like defining
mammals as "primates, whales, furry animals, ... (and so on)", which
works fine until you find a platypus.

Surely, there has to be a more generic way of defining a side effect.

Best regards,

Sidney

Nov 14 '05 #15
Sidney Cadot <si****@jigsaw.nl> wrote in message news:<bu**********@news.tudelft.nl>...
... But that just dismisses one of the possible 'side effects' admitted
by the standard.

Does a fopen(name, "rb") count as 'calling a function that does any of
those operations' ? I think it does; it /has/, at some point, to
interact with the abstract machine's environment, which can only be done
via volatile objects or modifying an object, eventually, somewhere
down the line.

Anyway, we can pick on words (and that's valuable) but if anything, this
shows that the enumeration of 'side effects' as given in the standard
is not exhaustive. Clearly, opening a file (even for reading) interacts
with the outside world, e.g. on unix systems it updates the 'last
accessed' date as pointed out. This is not unambiguously covered by the
standard; if upon literal reading we were to conclude that it isn't
properly covered - well, then the standard needs to be mended on the
next occasion.

The point is that the change your describing (the last accessed date)
is *not* visible to a standard C program, and an implementation could
therefore claim to be conforming even if it removed the open. I think
we'd all agree that such an implementation would have serious QoI
issues.
Nov 14 '05 #16
In article <40***************@yahoo.com>,
CBFalconer <cb********@yahoo.com> wrote:
I think it is purely pedantic.
It is purely pedantic because no existing compiler will remove the call
to fopen ().

On the other hand: If you are a compiler writer and you want to remove
this kind of call, then you have to _prove_ that the C Standard allows
it. If you are an application programmer and you want to make sure that
the call is not removed, then you could write

volatile FILE* p = fopen ("my file", "options);

and that will make it damned hard for the compiler writer to optimise
the call away.
At any rate there is no telling
what the act of opening a file involves, regardless of system. I
have built systems where the act of opening a particular named
file did some major re-arrangement of the entire i/o system, and
the act of closing that file put it back. This kept the
application proper coding standard and restricted the magic to
file system drivers.

Nov 14 '05 #17
In <NL********************@comcast.com> "Douglas A. Gwyn" <DA****@null.net> writes:
Jack Klein wrote:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


But that is *not* the way that Unix (POSIX) works!
Opening a file *does* have side effects in the environment.


But not according to the C standard (unless you can provide a chapter and
verse). Therefore, removing the fopen() call does not affect the
implementation's conformance to the C standard (which provides a complete
list of what it considers side effects).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #18
Jack Klein wrote:
....
Doh! I probably knew that, although I haven't had anything running
Linux in quite a while. It's time of creation that they don't keep
separately, right?


No - seperate times are kept for the creation date, last access, and the
last modification.
Nov 14 '05 #19
Da*****@cern.ch (Dan Pop) writes:
In <NL********************@comcast.com> "Douglas A. Gwyn"
<DA****@null.net> writes:
Jack Klein wrote:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


But that is *not* the way that Unix (POSIX) works!
Opening a file *does* have side effects in the environment.


But not according to the C standard (unless you can provide a
chapter and verse). Therefore, removing the fopen() call does not
affect the implementation's conformance to the C standard (which
provides a complete list of what it considers side effects).


Side effects include "modifying a file". In a Unix filesystem, a
directory can be treated as a file; so can the physical device
containing the filesystem.

This is admittedly stretching the point.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #20
Sidney Cadot <si****@jigsaw.nl> writes:
[...]
Another thing is that I think the standard's way of defining a "side
effect" (by enumeration of cases) is flawed. This is a bit like
defining mammals as "primates, whales, furry animals, ... (and so
on)", which works fine until you find a platypus.
A good example, only slightly damaged by the fact that platypuses do
have fur.
Surely, there has to be a more generic way of defining a side effect.


If the definition is too generic, it could include modifying memory
(which could be observed even if the program isn't running under a
debugger).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #21
Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <NL********************@comcast.com> "Douglas A. Gwyn"
<DA****@null.net> writes:
Jack Klein wrote:
> Given your reasoning, and I see nothing to argue with, optimizing away
> the fopen() is a perfectly acceptable application of the as-if rule on
> the typical *NIX system, where opening a file leaves no trace in the
> system.

But that is *not* the way that Unix (POSIX) works!
Opening a file *does* have side effects in the environment.


But not according to the C standard (unless you can provide a
chapter and verse). Therefore, removing the fopen() call does not
affect the implementation's conformance to the C standard (which
provides a complete list of what it considers side effects).


Side effects include "modifying a file". In a Unix filesystem, a
directory can be treated as a file; so can the physical device
containing the filesystem.

This is admittedly stretching the point.


After I posted this, I realized that a swap file or partition (if
there is one) can also be treated as a file, so modifying a variable
could conceivably "modify a file".

Intuitively, I think an fopen() call that updates a timestamp should
be considered a side effect, but modifying a non-volatile variable
shouldn't, even if it causes a write to a swap file. The trick is
figuring out how to state it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #22
On 2004-01-20 14:05, James Kuyper wrote:
Jack Klein wrote:
...
Doh! I probably knew that, although I haven't had anything running
Linux in quite a while. It's time of creation that they don't keep
separately, right?


No - seperate times are kept for the creation date, last access, and
the last modification.


The first one is not the creation date, but the last inode change date.
See `man 2 stat`.

-- Niklas Matthies
Nov 14 '05 #23
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <NL********************@comcast.com> "Douglas A. Gwyn"
<DA****@null.net> writes:
>Jack Klein wrote:
>> Given your reasoning, and I see nothing to argue with, optimizing away
>> the fopen() is a perfectly acceptable application of the as-if rule on
>> the typical *NIX system, where opening a file leaves no trace in the
>> system.
>
>But that is *not* the way that Unix (POSIX) works!
>Opening a file *does* have side effects in the environment.


But not according to the C standard (unless you can provide a
chapter and verse). Therefore, removing the fopen() call does not
affect the implementation's conformance to the C standard (which
provides a complete list of what it considers side effects).


Side effects include "modifying a file".


In the context of the C standard, opening a file for read access and
closing it doesn't modify its contents. The C standard blissfully
ignores any timestamping issues.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #24
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
> In <NL********************@comcast.com> "Douglas A. Gwyn"
> <DA****@null.net> writes:
> >Jack Klein wrote:
> >> Given your reasoning, and I see nothing to argue with, optimizing away
> >> the fopen() is a perfectly acceptable application of the as-if rule on
> >> the typical *NIX system, where opening a file leaves no trace in the
> >> system.
> >
> >But that is *not* the way that Unix (POSIX) works!
> >Opening a file *does* have side effects in the environment.
>
> But not according to the C standard (unless you can provide a
> chapter and verse). Therefore, removing the fopen() call does not
> affect the implementation's conformance to the C standard (which
> provides a complete list of what it considers side effects).


Side effects include "modifying a file". In a Unix filesystem, a
directory can be treated as a file; so can the physical device
containing the filesystem.

This is admittedly stretching the point.


After I posted this, I realized that a swap file or partition (if
there is one) can also be treated as a file, so modifying a variable
could conceivably "modify a file".


A swap file or partition is not a file, in the sense of the C standard.
A program with no side effects can cause the contents of the swap file
to be changed by the mere fact that it is partly or totally swapped out.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #25
In <40***************@saicmodis.com> James Kuyper <ku****@saicmodis.com> writes:
Jack Klein wrote:
...
Doh! I probably knew that, although I haven't had anything running
Linux in quite a while. It's time of creation that they don't keep
separately, right?


No - seperate times are kept for the creation date, last access, and the
last modification.


Nope, the creation date is not stored anywhere. There are three
timestamps associated to each file:

time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last inode change */

The field st_atime is changed by file accesses, e.g. by
exec(2), mknod(2), pipe(2), utime(2) and read(2) (of more
than zero bytes). Other routines, like mmap(2), may or may
not update st_atime.

Note, in the context of this discussion, that open() doesn't change
st_atime, a genuine read() call is needed for that.

The field st_mtime is changed by file modifications, e.g.
by mknod(2), truncate(2), utime(2) and write(2) (of more
than zero bytes). Moreover, st_mtime of a directory is
changed by the creation or deletion of files in that
directory. The st_mtime field is not changed for changes
in owner, group, hard link count, or mode.

The field st_ctime is changed by writing or by setting
inode information (i.e., owner, group, link count, mode,
etc.).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #26

In article <bu********@enews1.newsguy.com>, Chris Torek <no****@torek.net> writes:
Jack Klein <ja*******@spamcop.net> writes:
Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


In article <87************@pfaff.stanford.edu>,
Ben Pfaff <bl*@cs.stanford.edu> wrote:
Most Unix-like kernel, including Linux, also maintain "last
accessed" times. I don't know why you think they don't.


Moreover, if the file name corresponds to a fifo or named-pipe,
simply opening the file for reading can have an effect.


Opening a file for reading can have an effect even for regular files.
Consider a stock SysV kernel as described by Bach. A file-open
request can result in allocation of one or more in-core inodes and
so forth, and will (if successful) alter the process's file
descriptor table and so on.

These are implementation details of which a conforming program is
unaware, but they could have consequences in the environment. So
I think the original question still stands: does the as-if rule
apply to changes the program causes in the environment which are
not visible to a conforming program?

--
Michael Wojcik mi************@microfocus.com

But I still wouldn't count out the monkey - modern novelists being as
unpredictable as they are at times. -- Marilyn J. Miller
Nov 14 '05 #27

In article <be**************************@posting.google.com >, ro***********@yahoo.com (Robert Wessel) writes:
The point is that the change your describing (the last accessed date)
is *not* visible to a standard C program, and an implementation could
therefore claim to be conforming even if it removed the open. I think
we'd all agree that such an implementation would have serious QoI
issues.


However, it's entirely possible to imagine an implementation where a
conforming program could indirectly detect an effect of opening a
file for reading.

For example, consider an implementation which creates a file (in the
sense of "a filesystem object which can be opened using fopen") in a
temporary area for each file a program opens. These temporary files
are named using a predictable convention. A conforming program
could potentially determine how many files it had opened by attempting
to fopen (and then immediately fclose) these temporary files and seeing
how many such fopens succeeded.

That ought to work on a Linux system with the proc filesystem mounted,
for example, though I haven't actually tried it.

Such a program would get a different result before and after the
hypothetical fopen if that fopen were not optimized away. If it were
optimized away, of course, the program would get the same result
before and after the fopen. (Unless the implementation were clever
enough to understand the operation of the count-my-open-files
function and simulate the correct result - that is, extend the as-if
behavior to cover this aspect as well.)

Such a program would not be strictly conforming, since (to be useful)
it would have to produce output that depended on unspecified behavior,
but it could be conforming, as far as I can tell.

--
Michael Wojcik mi************@microfocus.com

Please enjoy the stereo action fully that will surprise you. -- Pizzicato Five
Nov 14 '05 #28
In <bu*********@enews4.newsguy.com> mw*****@newsguy.com (Michael Wojcik) writes:

In article <bu********@enews1.newsguy.com>, Chris Torek <no****@torek.net> writes:
>Jack Klein <ja*******@spamcop.net> writes:
>> Given your reasoning, and I see nothing to argue with, optimizing away
>> the fopen() is a perfectly acceptable application of the as-if rule on
>> the typical *NIX system, where opening a file leaves no trace in the
>> system.


In article <87************@pfaff.stanford.edu>,
Ben Pfaff <bl*@cs.stanford.edu> wrote:
>Most Unix-like kernel, including Linux, also maintain "last
>accessed" times. I don't know why you think they don't.


Moreover, if the file name corresponds to a fifo or named-pipe,
simply opening the file for reading can have an effect.


Opening a file for reading can have an effect even for regular files.
Consider a stock SysV kernel as described by Bach. A file-open
request can result in allocation of one or more in-core inodes and
so forth, and will (if successful) alter the process's file
descriptor table and so on.

These are implementation details of which a conforming program is
unaware, but they could have consequences in the environment. So
I think the original question still stands: does the as-if rule
apply to changes the program causes in the environment which are
not visible to a conforming program?


Nope, the as-if rule is defined exclusively in terms of the C abstract
machine, where the semantics of a file are as defined in the C standard.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #29
Sidney Cadot wrote:
Another thing is that I think the standard's way of defining a "side
effect" (by enumeration of cases) is flawed. This is a bit like defining
mammals as "primates, whales, furry animals, ... (and so on)", which
works fine until you find a platypus.
Surely, there has to be a more generic way of defining a side effect.


The problem is, there are numerous actual side effects, not all
of which are deemed essential for conformance purposes. I
alluded to some of them (timing, code size, etc.) in my previous
posting.
Nov 14 '05 #30
Christian Bau wrote:
I think it is purely pedantic.
It is purely pedantic because no existing compiler will remove the call
to fopen ().
That is true as far as I know. However, many functions /are/ optimized
away by modern compilers (e.g. abs(), or strlen() of a string literal),
so it isn't too far-fetched to suppose this is within reach.
On the other hand: If you are a compiler writer and you want to remove
this kind of call, then you have to _prove_ that the C Standard allows
it. If you are an application programmer and you want to make sure that
the call is not removed, then you could write

volatile FILE* p = fopen ("my file", "options);

and that will make it damned hard for the compiler writer to optimise
the call away.

At any rate there is no telling
what the act of opening a file involves, regardless of system. I
have built systems where the act of opening a particular named
file did some major re-arrangement of the entire i/o system, and
the act of closing that file put it back. This kept the
application proper coding standard and restricted the magic to
file system drivers.


It would be utterly silly if this kind of thing didn't qualify as a side
effect, wouldn't you agree?

Best regards,

Sidney

Nov 14 '05 #31
Keith Thompson wrote:
Sidney Cadot <si****@jigsaw.nl> writes:
[...]
Another thing is that I think the standard's way of defining a "side
effect" (by enumeration of cases) is flawed. This is a bit like
defining mammals as "primates, whales, furry animals, ... (and so
on)", which works fine until you find a platypus.

A good example, only slightly damaged by the fact that platypuses do
have fur.


Ah, what a pity.
Surely, there has to be a more generic way of defining a side effect.


If the definition is too generic, it could include modifying memory
(which could be observed even if the program isn't running under a
debugger).


Yes. It is intuitively quite clear what "side effect" should mean, but
it's hard to put it in words. However, that's exactly what members of
the Standards comittee are for.

To me it is also intuitively clear that opening a file should count as a
side effect. The fact that it's highly questionable that this stance is
backed by the standard means, IMHO, that the standard is wrong here.

Best regards,

Sidney

Nov 14 '05 #32
Dan Pop wrote:
These are implementation details of which a conforming program is
unaware, but they could have consequences in the environment. So
I think the original question still stands: does the as-if rule
apply to changes the program causes in the environment which are
not visible to a conforming program?


Nope, the as-if rule is defined exclusively in terms of the C abstract
machine, where the semantics of a file are as defined in the C standard.


As far as I can tell, the C standard does not define semantics of a
file. Surprisingly, I don't see "file" defined either.

So why not view a file as 'contents' + 'attributes'; in that case,
opening a file which may change attributes counts as "modifying the file".

Best regards,

Sidney

Nov 14 '05 #33
"Christian Bau" <ch***********@cbau.freeserve.co.uk> wrote in message
news:ch*********************************@slb-newsm1.svr.pol.co.uk...
On the other hand: If you are a compiler writer and you want to remove
this kind of call, then you have to _prove_ that the C Standard allows
it. If you are an application programmer and you want to make sure that
the call is not removed, then you could write

volatile FILE* p = fopen ("my file", "options);

and that will make it damned hard for the compiler writer to optimise
the call away.


Not if "my file" is an invalid filename and the compiler recognizes that and
generates code that sets p to NULL without calling any function.
Nov 14 '05 #34
In article
<V9******************@twister01.bloor.is.net.cable .rogers.com>,
"Wojtek Lerch" <Wo******@yahoo.ca> wrote:
"Christian Bau" <ch***********@cbau.freeserve.co.uk> wrote in message
news:ch*********************************@slb-newsm1.svr.pol.co.uk...
On the other hand: If you are a compiler writer and you want to remove
this kind of call, then you have to _prove_ that the C Standard allows
it. If you are an application programmer and you want to make sure that
the call is not removed, then you could write

volatile FILE* p = fopen ("my file", "options);

and that will make it damned hard for the compiler writer to optimise
the call away.


Not if "my file" is an invalid filename and the compiler recognizes that and
generates code that sets p to NULL without calling any function.


In that case you could very well argue that the call has no side
effects, even if calling fopen would usually have side effects.
Nov 14 '05 #35
Sidney Cadot <si****@jigsaw.nl> writes:
To me it is also intuitively clear that opening a file should count as a
side effect.
That's the problem with intuitions: To me it is intuitively clear that
opening a file should *not* count as a side effect (in the context of the
C language).
The fact that it's highly questionable that this stance is backed by the
standard means, IMHO, that the standard is wrong here.


I disagree. There's a reason why the scope of the C standard is limited.

In the real world, that's not a problem. Few (if any) C implementations
claim to implement ISO C and nothing else. Usually they try to follow
additional standards, some of which (e.g. POSIX) do indeed define file
timestamps, so that in the context of these standards, opening a file for
reading does have a well-defined side effect and can therefore not be
optimized away.

Martin
Nov 14 '05 #36
Martin Dickopp <ex****************@zero-based.org> wrote:
Sidney Cadot <si****@jigsaw.nl> writes:
To me it is also intuitively clear that opening a file should count as a
side effect.


That's the problem with intuitions: To me it is intuitively clear that
opening a file should *not* count as a side effect (in the context of the
C language).


Section 5.1.2.3 of the standard defined what a side effect is (a change in
the execution environment). Opening a file may have some effect on the
execution environment of the program is executing, in which it is a side
effect, or it may not, in which case, it would appear not to be a side
effect.

You could have magic filenames whose contents are encoded in the filename
(like data: URLs - which never seemed to catch on, for some reason).

f = fopen("data:Hello world\n", "r");

If the fopen was successful and 'f' now points to a FILE object that
represents this pseudo-file, does this count as a change in the execution
environment, and hence a side effect? I'm not sure.

--
Stewart Brodie
Nov 14 '05 #37
Martin Dickopp wrote:
Sidney Cadot <si****@jigsaw.nl> writes:

To me it is also intuitively clear that opening a file should count as a
side effect.

That's the problem with intuitions: To me it is intuitively clear that
opening a file should *not* count as a side effect (in the context of the
C language).


I have no intuition 'in the context of the C language' about files,
whatsoever. To me handling files is the job of the operating system and
the C standard ought to be non-explicit in what are and are not side
effects when doing /anything/ with a file.

A possible approach that just occurs to me would be to allow "volatile"
as a function attribute, meaning that the function is effectively
declared to communicate with the world outside the abstract machine,
with all bets off regarding side effects (no optimizations possible).
The fact that it's highly questionable that this stance is backed by the
standard means, IMHO, that the standard is wrong here.

I disagree. There's a reason why the scope of the C standard is limited.

In the real world, that's not a problem. Few (if any) C implementations
claim to implement ISO C and nothing else. Usually they try to follow
additional standards, some of which (e.g. POSIX) do indeed define file
timestamps, so that in the context of these standards, opening a file for
reading does have a well-defined side effect and can therefore not be
optimized away.


Dan Pop would probably argue that such a 'well-defined side effect' is
still not relevant to the compiler. C99 states exactly three things that
are side effects (for the compiler), and opening a file for reading is
not one of them, whether you do POSIX or not.

Best regards,

Sidney

Nov 14 '05 #38
"Christian Bau" <ch***********@cbau.freeserve.co.uk> wrote in message
news:ch*********************************@slb-newsm1.svr.pol.co.uk...
In article
<V9******************@twister01.bloor.is.net.cable .rogers.com>,
"Wojtek Lerch" <Wo******@yahoo.ca> wrote:
"Christian Bau" <ch***********@cbau.freeserve.co.uk> wrote in message
news:ch*********************************@slb-newsm1.svr.pol.co.uk...
On the other hand: If you are a compiler writer and you want to remove
this kind of call, then you have to _prove_ that the C Standard allows
it. If you are an application programmer and you want to make sure that the call is not removed, then you could write

volatile FILE* p = fopen ("my file", "options);

and that will make it damned hard for the compiler writer to optimise
the call away.


Not if "my file" is an invalid filename and the compiler recognizes that and generates code that sets p to NULL without calling any function.


In that case you could very well argue that the call has no side
effects, even if calling fopen would usually have side effects.


OK, that was a bad example. As a matter of fact, it only got posted because
I pushed the wrong button...

But imagine an implementation that doesn't use an OS or a real filesystem,
and its standard I/O functions operate on fake files implemented as data
structures in memory. The programmer can set up the initial contents of the
fake filesystem by putting them in a special header file that is included by
the implementation's <stdio.h>. After exit() has closed all streams, it
prints out the new contents of the fake filesystem. Is there anything in
the standard that makes it impossible for such an implementation to be
conforming?

The compiler automatically replaces a return statement in main() with a call
to exit(). The calls to fopen() and exit() get inlined, and so does the
fclose() call that exit() makes to close your stream. The optimizer notices
that the fclose() call reverses everything that your fopen() call did, and
optimizes them both out. Does this sound impossible or wrong?

Nov 14 '05 #39
Sidney Cadot <si****@jigsaw.nl> writes:
Martin Dickopp wrote:
In the real world, that's not a problem. Few (if any) C implementations
claim to implement ISO C and nothing else. Usually they try to follow
additional standards, some of which (e.g. POSIX) do indeed define file
timestamps, so that in the context of these standards, opening a file
for reading does have a well-defined side effect and can therefore not
be optimized away.
Dan Pop would probably argue that such a 'well-defined side effect' is
still not relevant to the compiler.


If he argued that this side effect is not relevant to the C standard
conformance of the compiler, I would certainly agree with him.
C99 states exactly three things that are side effects (for the
compiler), and opening a file for reading is not one of them, whether
you do POSIX or not.


A compiler which optimized away opening a file for reading would not be
conforming to the POSIX standard. It might still be conforming to the C
standard, of course.

Martin
Nov 14 '05 #40
Michael Wojcik wrote:
In article <be**************************@posting.google.com >, ro***********@yahoo.com (Robert Wessel) writes:

The point is that the change your describing (the last accessed date)
is *not* visible to a standard C program, and an implementation could
therefore claim to be conforming even if it removed the open. I think
we'd all agree that such an implementation would have serious QoI
issues.

However, it's entirely possible to imagine an implementation where a
conforming program could indirectly detect an effect of opening a
file for reading.

For example, consider an implementation which creates a file (in the
sense of "a filesystem object which can be opened using fopen") in a
temporary area for each file a program opens. These temporary files
are named using a predictable convention. A conforming program
could potentially determine how many files it had opened by attempting
to fopen (and then immediately fclose) these temporary files and seeing
how many such fopens succeeded.


Which could be a good way of doing it...

That ought to work on a Linux system with the proc filesystem mounted,
for example, though I haven't actually tried it.
[OT]
....except here. In /proc, the directories (which are named after
currently existant PIDs and contain files and directories containing
info relative to those processes) are created and destroyed along with
the processes. Which means that in a system with an uptime of more than
a few moments, they wouldn't exist in sequential order. In fact, the
`array' is quite sparse most of the time.

There are, of course, ways to work around this. But that would drag this
comment even further from the topic (of the thread and the newsgroup). ;)
[/OT]

Such a program would get a different result before and after the
hypothetical fopen if that fopen were not optimized away. If it were
optimized away, of course, the program would get the same result
before and after the fopen. (Unless the implementation were clever
enough to understand the operation of the count-my-open-files
function and simulate the correct result - that is, extend the as-if
behavior to cover this aspect as well.)
Heh. Any compiler that smart could phone in sick and spend the day
goofing off on Usenet. ;)

Such a program would not be strictly conforming, since (to be useful)
it would have to produce output that depended on unspecified behavior,
but it could be conforming, as far as I can tell.


Well, I suppose that your notion of `conforming' is different from my
own. If a program implicitly makes use of a highly system-specific
property, I'd consider it nonconformant and I wouldn't expect it to work
/at all/ in another system context. That fopen() trick is at the mercy
of all parts of the system, apparently including the compiler.

I would, however, want a compiler flag to tell the thing not to optimize
certain ways, or even not to optimize at all. But that's pure QoI.

--
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.
Nov 14 '05 #41
On Tue, 20 Jan 2004 09:11:53 +0000, Christian Bau
<ch***********@cbau.freeserve.co.uk> wrote in comp.std.c:
In article <40***************@yahoo.com>,
CBFalconer <cb********@yahoo.com> wrote:
I think it is purely pedantic.
It is purely pedantic because no existing compiler will remove the call
to fopen ().

On the other hand: If you are a compiler writer and you want to remove
this kind of call, then you have to _prove_ that the C Standard allows
it. If you are an application programmer and you want to make sure that
the call is not removed, then you could write

volatile FILE* p = fopen ("my file", "options);


I think not, but perhaps:

FILE * volatile p = fopen (/*...*/);

....might.

and that will make it damned hard for the compiler writer to optimise
the call away.
At any rate there is no telling
what the act of opening a file involves, regardless of system. I
have built systems where the act of opening a particular named
file did some major re-arrangement of the entire i/o system, and
the act of closing that file put it back. This kept the
application proper coding standard and restricted the magic to
file system drivers.


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #42
On Wed, 21 Jan 2004 02:03:29 +0100, Sidney Cadot <si****@jigsaw.nl>
wrote in comp.std.c:
Martin Dickopp wrote:
Sidney Cadot <si****@jigsaw.nl> writes:

To me it is also intuitively clear that opening a file should count as a
side effect.

That's the problem with intuitions: To me it is intuitively clear that
opening a file should *not* count as a side effect (in the context of the
C language).


I have no intuition 'in the context of the C language' about files,
whatsoever. To me handling files is the job of the operating system and
the C standard ought to be non-explicit in what are and are not side
effects when doing /anything/ with a file.

A possible approach that just occurs to me would be to allow "volatile"
as a function attribute, meaning that the function is effectively
declared to communicate with the world outside the abstract machine,
with all bets off regarding side effects (no optimizations possible).
The fact that it's highly questionable that this stance is backed by the
standard means, IMHO, that the standard is wrong here.

I disagree. There's a reason why the scope of the C standard is limited.

In the real world, that's not a problem. Few (if any) C implementations
claim to implement ISO C and nothing else. Usually they try to follow
additional standards, some of which (e.g. POSIX) do indeed define file
timestamps, so that in the context of these standards, opening a file for
reading does have a well-defined side effect and can therefore not be
optimized away.


Dan Pop would probably argue that such a 'well-defined side effect' is
still not relevant to the compiler. C99 states exactly three things that
are side effects (for the compiler), and opening a file for reading is
not one of them, whether you do POSIX or not.

Best regards,

Sidney


No, because the meaning of at least one of those definitions, the one
relevant to this discussion, is debatable:

5.1.2.3 P2 states that "modifying a file" is a side effect. It does
not say writing to a file or changing the contents of a file.

If the fopen() call changes an entry in the system's file system that
pertains to that particular file, that modifies the file without
changing its contents.

Whether or not the "modifying a file" phrase in the standard includes
that type of modification as a side effect is not spelled out one way
or the other, and perhaps should be.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #43
On 20 Jan 2004 07:44:14 GMT, those who know me have no need of my name
<no****************@usa.net> wrote in comp.std.c:
in comp.std.c i read:
On 19 Jan 2004 16:13:33 GMT, Da*****@cern.ch (Dan Pop) wrote in
comp.lang.c:

The only *relevant* side effects of fopen are those specified in the C
standard. Opening a file in read mode doesn't modify the file, therefore it doesn't
count as a side effect, in the context of the C standard.


Given your reasoning, and I see nothing to argue with, optimizing away
the fopen() is a perfectly acceptable application of the as-if rule on
the typical *NIX system, where opening a file leaves no trace in the
system.


actually unices typically do record the time a file was opened. dan might
argue that by itself that isn't sufficient, and in some ways i agree, but
there remains a flaw: there's no way to know whether the FILE object
contains a volatile member or would call the environment since it's
implementation defined.


But that's exactly the point, the implementation should know what's in
its implementation-defined headers, shouldn't it?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #44
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes: [...]
After I posted this, I realized that a swap file or partition (if
there is one) can also be treated as a file, so modifying a variable
could conceivably "modify a file".


A swap file or partition is not a file, in the sense of the C standard.


A swap file is a file if it has a name that can be used for a
successful call to fopen(). (Linux even has a "swapon" command that
causes an existing file to be used as a swap file.)
A program with no side effects can cause the contents of the swap file
to be changed by the mere fact that it is partly or totally swapped out.


Agreed -- and I agree that such a change should not be considered a
"side effect" as far as the C standard is concerned.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #45
Sidney Cadot wrote:

Dan Pop wrote:
These are implementation details of which a conforming program is
unaware, but they could have consequences in the environment. So
I think the original question still stands: does the as-if rule
apply to changes the program causes in the environment which are
not visible to a conforming program?


Nope, the as-if rule is defined exclusively in terms of the C abstract
machine, where the semantics of a file are as defined in the C standard.


As far as I can tell, the C standard does not define semantics of a
file. Surprisingly, I don't see "file" defined either.


N868 7.19.3 Files,
discusses files and their relationship to streams,
also uses "a terminal" and "a disk file" as two examples of files.

--
pete
Nov 14 '05 #46
In <bu*************@news.t-online.com> Martin Dickopp <ex****************@zero-based.org> writes:
A compiler which optimized away opening a file for reading would not be
conforming to the POSIX standard.


Could you post the chapter and verse? I can't find any mention that
open() in read mode modifies anything in the file inode.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #47
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
Da*****@cern.ch (Dan Pop) writes:
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:

[...]
>After I posted this, I realized that a swap file or partition (if
>there is one) can also be treated as a file, so modifying a variable
>could conceivably "modify a file".


A swap file or partition is not a file, in the sense of the C standard.


A swap file is a file if it has a name that can be used for a
successful call to fopen(). (Linux even has a "swapon" command that
causes an existing file to be used as a swap file.)


Once you activate swapping on a certain file, this file no longer has
the semantics of standard C file, even if you can access it from a C
program.
A program with no side effects can cause the contents of the swap file
to be changed by the mere fact that it is partly or totally swapped out.


Agreed -- and I agree that such a change should not be considered a
"side effect" as far as the C standard is concerned.


Then, what is your point?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #48
In <bu**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:
Dan Pop wrote:
These are implementation details of which a conforming program is
unaware, but they could have consequences in the environment. So
I think the original question still stands: does the as-if rule
apply to changes the program causes in the environment which are
not visible to a conforming program?
Nope, the as-if rule is defined exclusively in terms of the C abstract
machine, where the semantics of a file are as defined in the C standard.


As far as I can tell, the C standard does not define semantics of a
file.


Then, what does "7.19.3 Files" talk about?

Surprisingly, I don't see "file" defined either.
Which means that the definition must be taken from a normative reference,
such as ISO/IEC 2382-1:1993.
So why not view a file as 'contents' + 'attributes'; in that case,
opening a file which may change attributes counts as "modifying the file".


Where does the standard mention that fopen in read mode affects any
"file attributes"?

Where does the standard mention anything at all about "file attributes"?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #49
If puts is defined this way:

#include <stdio.h>
int puts(const char *s)
{
return fputs(s, stdout) > -1 ? fputc('\n', stdout) : EOF;
}

.... is there any way that the call to fputc in the above definition,
could return EOF ?

I think that there isn't, because the operation of the standard
output stream has already been verified by the call to fputs,
and the '\n' argument shouldn't cause any problems either.

Is there anything else involved ?

--
pete
Nov 14 '05 #50

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

68 posts views Thread by Marco Bubke | last post: by
3 posts views Thread by Jase | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.