473,883 Members | 1,956 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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
145 6368
Wojtek Lerch wrote:
....
The compiler automatically replaces a return statement in main() with a call
to exit().


That's not correct - such a re-write would not handle correctly calls to
main() frome within user code (which are legal). It's more accurate to
say that the initial call to main() is essentially equivalent to

exit(main(argc, argv));
Nov 14 '05 #51
pete wrote:

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.


You're implying that the "operation" of the standard output stream can't
change between the fputs() call and the fputc() call. Offhand, I can't
see any reason why that would be true. If nothing else, a critical
hardware component could fail between the two calls.
Nov 14 '05 #52
James Kuyper wrote:

pete wrote:

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.
You're implying that the "operation" of the
standard output stream can't change between the fputs()
call and the fputc() call.


I'm asking, yes.
Offhand, I can't see any reason why that would be true.
If nothing else, a critical hardware component could fail
between the two calls.


Wouldn't such a failure disqualify the implementation from being a
conforming one, and thus no longer subject to the standard ?

Is an implementation which issues all the right diagnostics during
translation, but generates no output for any C program, conforming ?

(I changed the subject line, because I accidenatlly wrote fgets)

--
pete
Nov 14 '05 #53
pete wrote:
(I changed the subject line, because I accidenatlly wrote fgets)


I did it again.

--
pete
Nov 14 '05 #54

In article <V1************ ******@fe02.use netserver.com>, August Derleth <se*@sig.now> writes:
Michael Wojcik wrote:
[examining /proc/<pid>/fd/*]
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.


#include <stdio.h>
int main(void)
{
FILE *fd = fopen("/proc/self/fd/0", "r");
if (fd) puts("This process has an open descriptor 0");
fclose(fd);
return 0;
}

appears to work on my Linux system, and does not appear to me to
be nonconforming; it uses only standard library calls. Extending
it to iterate through, say, the first 10 descriptor numbers to
find out how many files the process has open (up to 10) is trivial.
That in turn would allow it to detect the side effect of opening a
file for reading.

Of course, this is just intended as a real-world example of a
hypothetical implementation which would allow a program to detect
a side effect of such an fopen, and have output that depended on
it, resulting in a difference in program output if the fopen were
optimized away.
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.


I believe it's conforming because it only uses standard language
constructs and library calls. It should be "acceptable to any
conforming implementation" , which is how C90 defines conformance. It
won't *work* on all conforming implementations , certainly, in the
sense of doing what I'd like it to do; on many of them the fopens of
/proc/whatever will return NULL because that's not a valid filename.
But that doesn't make them nonconforming as defined in the standard.

Of course it's not strictly conforming, since its output depends on
implementation details.

Note that I'm not convinced myself that a conforming implementation
couldn't optimize away the "unused" fopen under the as-if rule. I
don't know if the standard's definition of side effect would include
the sort of thing I'm describing here. I only raise it because it
appears to be a side effect that can be detected by a conforming
program, unlike file timestamps and that sort of thing.

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

Ten or ten thousand, does it much signify, Helen, how we
date fantasmal events, London or Troy? -- Basil Bunting
Nov 14 '05 #55
In <40***********@ mindspring.com> pete <pf*****@mindsp ring.com> writes:
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 ?


Imagine that stdout is unbuffered and connected to a disk file
and the fputs call has written the last bytes available in the filesystem.
Where is the newline character going to be written by the fputc call?

As a general rule, if the standard doesn't guarantee that a certain
library function call will succeed, it can fail for unspecified reasons.
According to some committee members, even realloc(ptr, oldsize) is
allowed to fail, although it's logically a no-op.

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

James Kuyper wrote:

pete wrote:

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.
You're implying that the "operation" of the
standard output stream can't change between the fputs()
call and the fputc() call.


I'm asking, yes.
Offhand, I can't see any reason why that would be true.
If nothing else, a critical hardware component could fail
between the two calls.


Wouldn't such a failure disqualify the implementation from being a
conforming one, and thus no longer subject to the standard ?


Every I/O function described by the standard has explicit permission to
fail, and the standard is deliberately unspecific about the reasons why
they might fail. If a system starts out with two working hard disks, and
looses one during the running of a program, do you think it would
thereby become non-conforming? If so, could you cite the relevant
section of the standard that would be violated?
Is an implementation which issues all the right diagnostics during
translation, but generates no output for any C program, conforming ?


I believe so, so long as all of the relevant function calls return the
required indications of I/O failures.
Nov 14 '05 #57
James Kuyper wrote:

pete wrote:

James Kuyper wrote:

pete wrote:
>
> 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.

You're implying that the "operation" of the
standard output stream can't change between the fputs()
call and the fputc() call.


I'm asking, yes.
Offhand, I can't see any reason why that would be true.
If nothing else, a critical hardware component could fail
between the two calls.


Wouldn't such a failure disqualify the implementation from being a
conforming one, and thus no longer subject to the standard ?


Every I/O function described by the standard has explicit permission to
fail, and the standard is deliberately unspecific about the reasons why
they might fail. If a system starts out with two working hard disks, and
looses one during the running of a program, do you think it would
thereby become non-conforming? If so, could you cite the relevant
section of the standard that would be violated?


If the disk was the file that was associated with a stream,
then no more file, implies no more association.

N869
7.19.3 Files
[#1] A stream is associated with an external file (which may
be a physical device) by opening a file, which may involve
creating a new file.
Is an implementation which issues all the right diagnostics during
translation, but generates no output for any C program, conforming ?


I believe so, so long as all of the relevant function calls return the
required indications of I/O failures.


Thank you.

--
pete
Nov 14 '05 #58
Dan Pop wrote:

In <40***********@ mindspring.com> pete <pf*****@mindsp ring.com> writes:
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 ?


Imagine that stdout is unbuffered and connected to a disk file
and the fputs call has written the last bytes available in the
filesystem.
Where is the newline character going to be written by the fputc call?

As a general rule, if the standard doesn't guarantee that a certain
library function call will succeed,
it can fail for unspecified reasons.
According to some committee members, even realloc(ptr, oldsize) is
allowed to fail, although it's logically a no-op.


Thank you.

--
pete
Nov 14 '05 #59
Da*****@cern.ch (Dan Pop) writes:
In <ln************ @nuthaus.mib.or g> Keith Thompson <ks***@mib.or g> writes:
Da*****@cern.c h (Dan Pop) writes:
In <ln************ @nuthaus.mib.or g> Keith Thompson <ks***@mib.or g> 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.


Chapter and verse, please. C99 7.9.13 describes (in deliberately
vague terms) what a "file" is. It's clear that it can be a disk file
or a device (including a terminal). I see nothing in the description,
or anywhere else in the standard, that would exclude, for example, a
disk file or device to which the Linux "swapon" command has been
applied.
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?


My point is that, though common sense (at least mine) says that
updates to a swap file caused by updating a non-volatile variable
should not be considered side effects, I don't see that common sense
reflected in the wording of the standard (unless you can demonstrate
that a swap file is not a "file").

Perhaps it would suffice to add something to 5.1.2.3 saying that an
implementation may define that certain file updates are not side
effects. Or the phrase "modifying a file" could be changed to
"explicitly modifying a file".

Or (this is an interpretation I just thought of), we could decide that
it's the operating system, not the program, that modifies the swap
file, so it's not considered a side effect *of the program*, even
though it was indirectly caused by the execution of the program.

However it's interpreted and/or modified, I doubt that any
implementers will actually avoid optimizations just because they might
modify a swap file. The discussion, I think, is about wording, not
about intent.

--
Keith Thompson (The_Other_Keit h) 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 #60

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

49
2895
by: Ville Vainio | last post by:
I don't know if you have seen this before, but here goes: http://text.userlinux.com/white_paper.html There is a jab at Python, though, mentioning that Ruby is more "refined". -- Ville Vainio http://www.students.tut.fi/~vainio24
68
4408
by: Marco Bubke | last post by:
Hi I have read some mail on the dev mailing list about PEP 318 and find the new Syntax really ugly. def foo(x, y): pass I call this foo(1, 2), this isn't really intuitive to me! Also I don't like the brackets.
3
1430
by: Jase | last post by:
For some reason all of a sudden "£" signs are displaying as "?" when the field is displayed. The display code is: <%=rs.Fields("WagesText")%> This was working fine before, so I have no idea why it has suddenly changed. The code hasn't altered as far as I'm aware but it is a possibility. The database is SQL based.
27
5102
by: Curious Angel | last post by:
I have a resume in PDF format and I want anyone who LEFT-OR-RIGHT clicks the link to force the file to be saved, and in any event _not_ opened. Since the PDF will be in his cache in any event, I would just as soon place the employer in control of what directory he wishes to save it in, and there are two salient reasons for this: 1. I want him to OWN the document 2. I want him to FIND the document, quickly, on his hard drive In any...
0
364
by: Daniel | last post by:
how to make sure a xsl document has valid xsl syntax? i tried loading it into an xml document but that doesnt show syntax errors inside attributes such as "foo/bar" vs "bar\foo"
2
12186
by: Petr Jakes | last post by:
Hi, I am trying to set-up communication to the coin change-giver from my Linux box using the Python code. The change giver uses MDB (Multi Drop Bus) serial protocol to communicate with the master. MDB protocol is the 9bit serial protocol: (TX, RX lines only) 9600bps, 9bits, No Parity, 1 Start, 1 Stop. I would like to control the UART "parity bit" to try to simulate 9bit communication.
72
4290
by: Paminu | last post by:
In math this expression: (a < b) && (b < c) would be described as: a < b < c But why is it that in C these two expressions evaluate to something different for the same values of a, b and c?
5
1811
by: ZSP747 | last post by:
Now,I prepare to write a English-Chinese dictionary. So I want find a function or library can convert the words from one form to another,such as "boys"->"boy","became->become","went"->"go". Because there is so many unregular convertions in English then I think it will be a hard work if do it by myself. Thanks.
0
9786
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11125
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10836
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9568
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7114
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5794
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5982
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4211
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3230
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.