473,834 Members | 1,592 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

complier problem

Hi

My question is : Would the expression *p++=c be disallowed by the
complier.
The answer given in the book is: No.Because here even though the vlue
of p is acced twice it is used to modify two different objects p and
*p.
so can anyone explain this answer to me detail

Jul 28 '06 #1
11 2647


neha wrote On 07/28/06 10:52,:
Hi

My question is : Would the expression *p++=c be disallowed by the
complier.
The answer given in the book is: No.Because here even though the vlue
of p is acced twice it is used to modify two different objects p and
*p.
so can anyone explain this answer to me detail
Before:

c = 42

p --[ 3 ]
[ 1 ]
[ 4 ]

After:

c = 42

[ 42 ]
p --[ 1 ]
[ 3 ]

Two things have changed: The value of c has been copied
to the object p formerly pointed to, and p has been
incremented to point to the next object. The first was
caused by *(something) = c, the second by the p++.

--
Er*********@sun .com

Jul 28 '06 #2
neha wrote:
...
My question is : Would the expression *p++=c be disallowed by the
complier.
...
The answer given in the book is: No.Because here even though the vlue
of p is acced twice it is used to modify two different objects p and
*p.
...
The question does not provide enough information for an answer. And the given
answer does not make sense at all. What book is it? If it says what you say it
says, then you better get another book.

Note, that the question is specifically about whether the expression is allowed
or disallowed by the compiler or, in other words, whether the expression is
well-formed or ill-formed. In order to answer the question we need to know the
types of 'p' and 'c'. For example, if 'p' is of type 'void*', then it is illegal
to apply the '++' operator to it and the compiler will disallow it. If 'p' is of
type 'double*' and 'c' is of type 'struct Foo', then we have completely
unrelated types in assignment, which will also cause a diagnostic from the
compiler. And so on. Without having this extra information, there's no way to
say whether there's something there that must cause the compiler to complain.

The proposed answer, on the other hand, seems to address the well-known issue of
violating the object-access-and-sequence-points rule (don't know a better name
for it). Even if this rule is violated in some code, it does not make the code
ill-formed, i.e. no diagnostic is required from the compiler. It won't be
"disallowed " by the compiler even if there's a problem there. Instead, the code
will produce undefined behavior. There many are other ways, BTW, how the above
expression might produce undefined behavior. But this is irrelevant, since it
has nothing to do with being "disallowed by the compiler".

--
Best regards,
Andrey Tarasevich
Jul 28 '06 #3
neha posted:
My question is : Would the expression *p++=c be disallowed by the
complier.

I presume that that's a typo for:

*p++ = p;
Which means:

Take the object pointed at by "p", and store the value "p" in it. Then
increment "p". Quite like:

*p = p;

++p;

Which, in full context, would have to be something like:

int main()
{
void *ptr[2] = 0;

void **p = ptr;

*p++ = p;
}

--

Frederick Gotham
Jul 28 '06 #4
Eric Sosman wrote:
neha wrote On 07/28/06 10:52,:
Hi

My question is : Would the expression *p++=c be disallowed by the
complier.
The answer given in the book is: No.Because here even though the vlue
of p is acced twice it is used to modify two different objects p and
*p.
so can anyone explain this answer to me detail

Before:

c = 42

p --[ 3 ]
[ 1 ]
[ 4 ]

After:

c = 42

[ 42 ]
p --[ 1 ]
[ 3 ]

Two things have changed: The value of c has been copied
to the object p formerly pointed to, and p has been
incremented to point to the next object. The first was
caused by *(something) = c, the second by the p++.
Actually three things have changed but I take it that one
of those changes is a typo.
Frederick Gotham wrote:
neha posted:
My question is : Would the expression *p++=c be disallowed by the
complier.


I presume that that's a typo for:

*p++ = p;
No , I think that the opening poster wrote what he intended.
He says "the value of p is accessed twice" which seems to
exclude *p++ = p

Spiros Bousbouras

Jul 28 '06 #5


Frederick Gotham wrote On 07/28/06 12:56,:
neha posted:

>>My question is : Would the expression *p++=c be disallowed by the
complier.

I presume that that's a typo for:

*p++ = p;
Which means:

Take the object pointed at by "p", and store the value "p" in it. Then
increment "p". Quite like:

*p = p;

++p;
`*p+ = p' exhibits undefined behavior that the two-line
rewrite does not. 6.5, paragraph 2:

"[...] Furthermore, the prior value shall be read
only to determine the value to be stored."

In `*p++ = p' there are two reads of p's value: the permitted
read on the l.h.s. as part of the ++, and another on the r.h.s.
(Some may think there's a third read to determine the value
that * dereferences, but not so: that value is not the value
of p, but the value of the subexpression p++.)

To put it another way: Why in the two-line rewrite did you
choose to put the assignment first and the increment second?
You could just as well have written

++p;
*p = p;

or (abusing C's syntax to emphasize the U.B.)

++...
*p = p;
...p;

--
Er*********@sun .com

Jul 28 '06 #6
In article <11************ **********@i42g 2000cwa.googleg roups.com>
neha <ne*********@gm ail.comwrote:
>My question is : Would the expression *p++ = c be disallowed by the
complier.
(As an aside, remarkably few things are "disallowed " in C even if they
make no sense. :-) See <http://web.torek.net/torek/c/compiler.html>
for additional remarks.)
>The answer given in the book is: No.Because here even though the vlue
of p is acced twice it is used to modify two different objects p and
*p.
This answer is ... not so great.

Let us assume that the expression:

*p++ = c

is made into a complete statement, so that there are "sequence
points" before and after it. We might as well also assume that p
and c have appropriate types and useful values, otherwise the entire
thing falls apart.

Given these assumptions, we can next note that:

*p++ = c;

is parsed the same as:

(*(p++)) = (c);

This has four sub-expressions, each of which may be evaluated in
any order (perhaps even in parallel), with the obvious requirement
that the value of the "something" s below be known by the time they
are used:

p++

c

*(something) [specifically *p]

(something) = (something) [specifically *p = c]

Each of these four sub-expressions produces a value (of some type);
each can, but need not, also have some "side effect". A "side
effect" is, essentially, a change to something in memory: putting
a new value in some object. (In computer science, "side effects"
can also refer to printing output and the like, but we can ignore
all that here.)

Two of the four expressions above do in fact have side effects,
namely, "p++" and "(something ) = (something)".

In C, side effects that cause modifications to objects are allowed
to take place anywhere between "sequence points". If you wish to
avoid undefined behavior, you -- the programmer -- must make sure
that when you make such modifications, you do not "re-access" the
value of the object later, unless the "next" sequence point has
already happened, so that the new value has had time to settle in
to its object.

Think of the new values as raw eggs being tossed in in the air by
a juggler. He is allowed to get as many eggs (values) in the air
as he likes, as long as he catches them all by the next sequence
point, and packs them carefully into their egg-holders (objects)
by then.

What happens if you throw *two* raw-egg-values into the air, aiming
both of them at the same egg-holder? One likely answer is: they
collide and break, making a big mess. So "don't do that".

Now, in this case, we have two new values that have to happen:
"value of p + 1" goes into "p", and "value of c" goes into "*p".
This is where the most subtle point comes in.

The expression "*p = c" modifies *p. Of course, this needs the
value of "p". So "*p++" modifies *p++ ... which needs the value
of ... what?

The obvious (and correct) answer is "the value of p++", but what
exactly *is* the "value of p++"? The answer is *not* "go back and
look at p again", and this is a crucial point! The value of
"p++" is the value p had before the new p+1 value goes into p,
but this value has been "captured", in a sense, by tossing it
up into the air, as one of those raw eggs.

In other words, when you have:

*p++ = c;

the compiler can toss "the value of c" into the air; it does toss
"the old value of p, before incrementing" into the air; and it can
now toss "the new value of p, after incrementing" into the air.
At this point, it has everything it needs to handle the ordinary
assignment expression: it grabs "the old value of p" out of the
air and feeds that to the unary "*" operator. This finds whatever
object is at "*(old value of p)". Since the point of finding that
object is to change it -- to set it to "the value of c" -- the
compiler now aims "the value of c" (either getting it and tossing
it in the air now, if needed, or using the one that is already
there) at this object. The "value of c" egg is now aimed at the
"object at *old_p" egg-cup.

(At this point, there are only two values in the air: "value of c"
aimed towards *old_p and "new value for p" aimed at p. What happened
to "four expressions"? Well, one of them -- *(something) -- was
used to locate an object, so it is not "in the air" anymore. The
last one is the value of the entire assignment, i.e., the value
once *(something) is set. This value is aimed at the trash-can,
so if the compiler is any good, it does not even bother throwing
it up into the air in the first place.)

Now we come to the sequence point. Here, all the action has to
stop for a moment: the new value for p has to get stored safely
into p, and the new value for *(old value of p) has to get stored
safely there. All the "eggs" land in their targets -- with the
value of the overall assignment going into the trash -- and the
sequence point is satisfied; now the compiler can move on to the
next statement.
--
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.
Jul 28 '06 #7
Chris Torek wrote:
>
The obvious (and correct) answer is "the value of p++", but what
exactly *is* the "value of p++"? The answer is *not* "go back and
look at p again", and this is a crucial point! The value of
"p++" is the value p had before the new p+1 value goes into p,
but this value has been "captured", in a sense, by tossing it
up into the air, as one of those raw eggs.
...
Well, while it is true that what we need is the old value of 'p', what you are
saying seems to imply that the only way to obtain that old value of 'p' is to
preserve it ("capture it", "toss it into the air") when it is still available
(before 'p' is incremented). In reality, it is not required to be that way. The
compiler is free to perform the increment first without making any attempts to
"capture" the old value of 'p' and later, when it actually needs the old value
of 'p', it can obtain it by subtracting 1 from the current (already incremented)
value of 'p'.

--
Best regards,
Andrey Tarasevich

Jul 28 '06 #8
[in a situation in which the value of "p++" is used...]

In article <12************ *@news.supernew s.com>,
Andrey Tarasevich <an************ **@hotmail.comw rote:
>Well, while it is true that what we need is the old value of 'p',
what you are saying seems to imply that the only way to obtain that
old value of 'p' is to preserve it ("capture it", "toss it into
the air") when it is still available (before 'p' is incremented).
In reality, it is not required to be that way. The compiler is free
to perform the increment first without making any attempts to
"capture" the old value of 'p' and later, when it actually needs
the old value of 'p', it can obtain it by subtracting 1 from the
current (already incremented) value of 'p'.
This is a valid implementation-specific technique (via the
"as-if" rule), provided p itself is not marked volatile.

That is, regardless whether the compiler turns:

save = p++;

into:

/* effective C code; and machine instructions */
save = p; /* add r1, 0, r2 */
p = p + 1; /* add r1, 1, r1 */

or:

p = p + 1; /* add r1, 1, r1 */
save = p - 1; /* add r1, -1, r2 */

the outcome is the same, as long as p is not "volatile". (And the
code runs just as fast either way, since both sequences use two
"add" instructions with embedded immediate constants; the only
difference is the value of those constants.)

If p *is* marked "volatile", however, the compiler cannot use the
second sequence, since that causes two reads from the object. (As
yet another wrinkle, "what constitutes an access" to one of these
things marked volatile "is implementation-defined", so if the
implementation can provide a particularly interesting interpretation,
it may actually be able to do the "add one, then re-read, then
subtract one" after all.)
--
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.
Jul 28 '06 #9
Ark
Chris Torek wrote:
[in a situation in which the value of "p++" is used...]

In article <12************ *@news.supernew s.com>,
Andrey Tarasevich <an************ **@hotmail.comw rote:
>Well, while it is true that what we need is the old value of 'p',
what you are saying seems to imply that the only way to obtain that
old value of 'p' is to preserve it ("capture it", "toss it into
the air") when it is still available (before 'p' is incremented).
In reality, it is not required to be that way. The compiler is free
to perform the increment first without making any attempts to
"capture" the old value of 'p' and later, when it actually needs
the old value of 'p', it can obtain it by subtracting 1 from the
current (already incremented) value of 'p'.

This is a valid implementation-specific technique (via the
"as-if" rule), provided p itself is not marked volatile.

That is, regardless whether the compiler turns:

save = p++;

into:

/* effective C code; and machine instructions */
save = p; /* add r1, 0, r2 */
p = p + 1; /* add r1, 1, r1 */

or:

p = p + 1; /* add r1, 1, r1 */
save = p - 1; /* add r1, -1, r2 */

the outcome is the same, as long as p is not "volatile". (And the
code runs just as fast either way, since both sequences use two
"add" instructions with embedded immediate constants; the only
difference is the value of those constants.)

If p *is* marked "volatile", however, the compiler cannot use the
second sequence, since that causes two reads from the object. (As
yet another wrinkle, "what constitutes an access" to one of these
things marked volatile "is implementation-defined", so if the
implementation can provide a particularly interesting interpretation,
it may actually be able to do the "add one, then re-read, then
subtract one" after all.)
Looks like a storm in a teacup. ['save' doesn't have to exist at all,
depending on the instruction set, and *p++=c; may execute in a single
instruction]
p++ has a value (old p) and a side effect (p = old p + 1).
*p++ dereferences the value of p++ (old p).
I'd care about implementation only when shopping for a compiler (or
squeezing out that last optimization)
Sorry, fail to see any mystery or flying eggs :)
Regards,
Ark
Jul 29 '06 #10

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

Similar topics

0
1423
by: Francisco J. Reyes | last post by:
I get an Internal complier error when compiling C# windows project that uses a custom Class add as reference to the project. The problem appears to be related to the ENUM type used in the class controland where the windows project attempts to call the custom class property set\get a specific value using enum values from the custom class. Thanks in advance.
3
1685
by: Ygn | last post by:
#include <stdio.h> #include <winsock2.h> #include <windows.h> #include <process.h> #include <string.h> #include <winbase.h> #include <sys/socket.h> I would like to do compiling this header. When I try with my VC ++ I got error. So what the name of complier and where can I get it.
5
2754
by: Seven Kast USA | last post by:
Hi pelase explain me complier design of c and i need a small example complier design all phases in c programming . by KAST
2
4172
by: qbin_wang | last post by:
Hi: now i want to download a free c complier which can be used in windows system.and i see many posts in the comp.lang.c,but i don't find the answer.who can tell me the true and correct website that can download the c complier or tell me the c complier's name. thanks a lot.
2
3145
by: Ali Alsaffar | last post by:
Hi there, - I updated my windows XP professional with all critical updates available at windowsupdate.com - I updated Microsoft .NET Framework 1.1.4322 from thier also - I installed Visual Basic 6 Enterprise Edition - Then I also installed Visual Basic .NET 2003 Professional Edition - I created a new project in Visual Basic 6 successfully - Here is the problem: I failed to create a new Visual Basic project in Visual Basic .NET 2002 I got...
8
7099
by: shannon | last post by:
Hi there, Does anyone know if you can download a free javascript complier from the net. I need to check my code for a project. Thanks Shannon.
11
2286
by: jryden | last post by:
I wrote the following code into a console program in Visual C++6. If you build a release build and select custom optimizations and select 'general optimizations' as the only optimization then you will end up with incorrect results. Every line seems to be important, even the unrelated bits. Any one have the time or inclination to try this out for themselves and try to explain it? #include "stdafx.h" #include <string>
1
2528
by: tccode97 | last post by:
Hi, I need an urgent help. I am developing a socket application in VC++ that uses asynchronous connnection. After doing search on google, I found the following link http://msdn2.microsoft.com/en-us/library/system.net.sockets.udpclient...
16
10111
by: sriever4u | last post by:
I am new to ARM linux, i am working on AT91RM9200 board and using ARM linuc C complier.. i want to know how to produce nanosecond delay using software...
0
9797
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
9644
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,...
1
10547
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
9331
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
7757
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
6954
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
5793
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3977
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3081
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.