473,836 Members | 1,549 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 6361
>la************ @ugsplm.com wrote:
And note that there's no good reason to use fputc() rather than
putc() in this case. (In fact, there almost never a good reason
to use fputc).

In article <news:40******* ********@yahoo. com>
CBFalconer <cb********@wor ldnet.att.net> writes: n = 3;
....
putc(n++ + '0');


This is guaranteed to "work right" (i.e., putc '3' and leave n set
to 4, assuming n is still 3 at the previous sequence point), given
the obvious fix -- either putchar() or putc(..., stdout). The
one that might fail is:

FILE *files[N], **fpp;
...
for (fpp = &files[0]; fpp < &files[N];)
putc(expr, *fpp++);

Here the side effect on fpp might occur more than once, and/or
introduce undefined behavior.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.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 #71
Chris Torek wrote:
la************ @ugsplm.com wrote:
And note that there's no good reason to use fputc() rather than
putc() in this case. (In fact, there almost never a good reason
to use fputc).


In article <news:40******* ********@yahoo. com>
CBFalconer <cb********@wor ldnet.att.net> writes:
n = 3;
....
putc(n++ + '0');


This is guaranteed to "work right" (i.e., putc '3' and leave n set
to 4, assuming n is still 3 at the previous sequence point), given
the obvious fix -- either putchar() or putc(..., stdout).


I don't think so.
The standard says that putc can be implemented as a macro which
evaluates it's argument more than once,
"so the argument should never be an expression with side effects."
(C89 last public draft)

--
pete
Nov 14 '05 #72
James Kuyper <ku****@saicmod is.com> wrote in message news:<40******* ********@saicmo dis.com>...
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));


I was afraid someone was going to say that... I ignored this
possibility because it doesn't really have much to do with the topic
and makes my imaginary implementation a bit more complicated and a bit
less realistic.

But not impossible -- here's a workaround:

If a translation unit defines main(), the compiler generates a special
startup function that calls main() and then exit() exactly the way the
standard requires. When compling this special function, the compiler
decides to inline the calls to main() and exit(), and then everything
else happens the way I described before.

Does that look OK now?
Nov 14 '05 #73
In comp.std.c CBFalconer <cb********@yah oo.com> wrote:

putc(n++ + '0');


putc() takes *two* arguments -- the character and a stream. It's
allowed to evaluate the *stream* more than once, but not the character,
so that code is correct once the missing stream argument is added. In
my experience, side effects in the character argument are very rare
(although one can come up with plausible examples, as above) and side
effects in the stream argument are rare to the point of nonexistence.

-Larry Jones

I think we need to change the rules. -- Calvin
Nov 14 '05 #74
In article <40***********@ mindspring.com>
pete <pf*****@mindsp ring.com> writes:
The standard says that putc can be implemented as a macro which
evaluates it's argument more than once,
"so the argument should never be an expression with side effects."
(C89 last public draft)


Here is what a C99 draft says, which I believe is the same as
the final C89 wording:

[#2] The putc function is equivalent to fputc, except that
if it is implemented as a macro, it may evaluate stream more
than once, so the argument should never be an expression
with side effects.

In other words, putc() is explicitly allowed to evaluate its second
argument more than once, but not its first (giving rise to the
situation I described). My original stdio implementation of putc()
is rather complicated because of this -- the character to be output
gets stored in a byte attached to the underlying FILE object so
that the result can be evaluated more than once.

(POSIX threads eventually doomed the idea of inline expansion of
putc after all, so these days, the BSD/OS putc() is just an ordinary
function anyway.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.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 #75
CBFalconer <cb********@yah oo.com> wrote in message news:<40******* ********@yahoo. com>...
Dan Pop wrote:
... snip ...

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.


And, on some systems, is fairly likely to.


What, fail? [More likely, obviously, but fairly likely?!]
Those systems
mindlessly perform a malloc(size), check for success, and copy all
old data over. If all went well they free the old pointer. All
perfectly valid.


I've read articles that this behaviour is chosen because of a literal
interpretation of the standard: "...returns a pointer to a _new_
object". So, it's over-pedantism, rather than mindlessness. ;)

--
Peter
Nov 14 '05 #76
Chris Torek wrote:

In article <40***********@ mindspring.com>
pete <pf*****@mindsp ring.com> writes:
The standard says that putc can be implemented as a macro which
evaluates it's argument more than once,
"so the argument should never be an expression with side effects."
(C89 last public draft)


Here is what a C99 draft says, which I believe is the same as
the final C89 wording:

[#2] The putc function is equivalent to fputc, except that
if it is implemented as a macro, it may evaluate stream more
than once, so the argument should never be an expression
with side effects.

In other words, putc() is explicitly allowed to evaluate its second
argument more than once, but not its first (giving rise to the
situation I described). My original stdio implementation of putc()
is rather complicated because of this -- the character to be output
gets stored in a byte attached to the underlying FILE object so
that the result can be evaluated more than once.

(POSIX threads eventually doomed the idea of inline expansion of
putc after all, so these days, the BSD/OS putc() is just an ordinary
function anyway.)


A closer reading of my C89 last draft, shows the same thing.
Thank you.

--
pete
Nov 14 '05 #77
Chris Torek wrote:
CBFalconer <cb********@wor ldnet.att.net> writes:
la************ @ugsplm.com wrote:
And note that there's no good reason to use fputc() rather than
putc() in this case. (In fact, there almost never a good reason
to use fputc).

n = 3;
....
putc(n++ + '0');


This is guaranteed to "work right" (i.e., putc '3' and leave n set
to 4, assuming n is still 3 at the previous sequence point), given
the obvious fix -- either putchar() or putc(..., stdout). The
one that might fail is:

FILE *files[N], **fpp;
...
for (fpp = &files[0]; fpp < &files[N];)
putc(expr, *fpp++);

Here the side effect on fpp might occur more than once, and/or
introduce undefined behavior.


What guarantees that one macro parameter is evaluated only once,
and not the other? I know there are some special cases in the
standard, but on principle I wouldn't rely on it. I thought that
in general standard functions may be implemented as macros,
provided they never evaluate arguments more than once, but that
putc (and getc) were exceptions. Thus fputc and fgetc must be
available.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 14 '05 #78
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:
>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.


Data read in from a text stream
will necessarily compare equal to the data that were earlier
^^^^^^^^^^^
written out to that stream only if: the data consist only of
printing characters and the control characters horizontal tab
and new-line; no new-line character is immediately preceded by
space characters; and the last character is a new-line character.

Connect the text stream to an active swap file and the above guarantee
is no longer satisfied by the implementation.

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

Chris Torek wrote:

....
FILE *files[N], **fpp;
...
for (fpp = &files[0]; fpp < &files[N];)
putc(expr, *fpp++);

Here the side effect on fpp might occur more than once, and/or
introduce undefined behavior.


What guarantees that one macro parameter is evaluated only once,
and not the other? I know there are some special cases in the


7.19.7.8p2: "The putc function is equivalent to fputc, except that if it
is implemented as a macro, it may evaluate stream more than once, so
that argument should never be an expression with side effects."

An implementation of putc() as a macro which evaluated it's first
argument more than once would inequivalent to fputc(), in a way other
than the only allowed exception to that equivalence.
Nov 14 '05 #80

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

Similar topics

49
2885
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
4399
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
5097
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
12184
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
4275
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
1806
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
9818
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10843
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...
0
10254
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9371
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...
1
7790
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6978
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
5648
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
5825
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4015
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.