|
Chris Losinger wrote:
i read this whole post and didn't see a single question mark
You're right, sort of. There's a question mark in the subject line.
Chris Losinger wrote:
the post-increment operator can generate code that leads to undefined compiler behavior
The post-increment operator actually works just like it's supposed to. We, as humans, however, don't seem to understand as well, so we call it 'undefined'.
Chris Losinger wrote:
the code can generally be re-written in a way that avoids the situation
This is absolutely correct. Our code should always strive for simplicity, even if it makes the code long or unelegant.
Danny
|
|
|
|
|
bugDanny wrote:
The post-increment operator actually works just like it's supposed to. We, as humans, however, don't seem to understand as well, so we call it 'undefined'.
In and of itself, yes, but when combined with other expressions, we can't say for sure which order the compiler will evaluate the various dependent parts in. That's the part that is undefined.
bugDanny wrote:
Our code should always strive for simplicity...
Agreed. Because the compiler happens to evaluate an expression in the order a programmer wanted, the programmer assumes that since it works it must be okay.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
ok... i see it the time of increment is not defined by c++.
i also agree about simplicity. this was a principal question.
The function call example was a good idea.
printf("%d", x++);
But have in mind that x++ returns the current value of x and it is passed to printf. Then we don't care when x will be incremented. We'll always print what we have passed as an argument.
I don't agree that
y = x + x++;
is defined.
As most of you will agree i guess, the compiler reserves the right to evaluate operands and function arguments in any order.
-- modified at 3:13 Friday 16th September, 2005
|
|
|
|
|
pesho2932 wrote:
Then we don't care when x will be incremented
This is the point that I was unfortunately able to make. The exact point at which that increment takes place is unknown and unspecified; only the sequence-point semantics need to be satisfied. This allows compilers to either increment in-place after making a copy or make an incremented copy which does not have to be set until the value is next needed, which by definition is after the sequence point.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
pesho2932 wrote:
I don't agree that
y = x + x++;
is defined.
As most of you will agree i guess, the compiler reserves the right to evaluate operands and function arguments in any order.
I suppose this could be true. It could be my fault in believing the writer I quoted in an earlier quote, Tony Gaddis, who said:
"Postfix mode causes the increment to happen after the value of the variable is used in the expression."
If Gaddis is right, then the increment happens after x is used in the expression x + x
But perhaps someone did think it would be funny to mess with this behavior in the compiler to screw us programmers up. I did find a few good quotes on the matter:
Argument is conclusive... but... it does not remove doubt, so that the mind may rest in the sure knowledge of the truth, unless it finds it by the method of experiment. For if any man who never saw fire proved by satisfactory arguments that fire burns. his hearer's mind would never be satisfied, nor would he avoid the fire until he put his hand in it that he might learn by experiment what argument taught.
Bacon, Roger
1214-1294 British Philosopher Scientist
It is not necessary to understand things in order to argue about them.
Beaumarchais, Pierre De
1732-1799 French Dramatist
Men's arguments often prove nothing but their wishes.
Colton, Charles Caleb
1780-1832 British Sportsman Writer
It is better to debate a question without settling it than to settle it without debate.
Joubert, Joseph
1754-1824 French Moralist
If you argue with a woman and win, you lose.
Unknown, Source
That last one doesn't really apply, but I thought it was a good quote.
Danny
-- modified at 9:18 Friday 16th September, 2005
|
|
|
|
|
bugDanny wrote:
"Postfix mode causes the increment to happen after the value of the variable is used in the expression."
This is undoubtfully true. However, I don't see what it has to do with my previous post.
Now I absolutely agree with DavidCrowe and I don't think there is more to be said. I was just unsure wheter "after" in C++ specification means "immediately after" or "sometime after but before the end of the statement"... It looks like the latter one holds.
|
|
|
|
|
pesho2932 wrote:
bugDanny wrote:
"Postfix mode causes the increment to happen after the value of the variable is used in the expression."
This is undoubtfully true. However, I don't see what it has to do with my previous post.
Sorry, I thought you had asked whether the x++ would affect the other x before it was added together to assign to y. If that was what you were asking, then the quote shows that the increment happens after x + x is evaluated. If that wasn't what you were asking, then your question does not matter.
pesho2932 wrote:
Now I absolutely agree with DavidCrowe and I don't think there is more to be said.
Yes, please. But if you mean it, don't refute what someone says, then say you're done talking about it. I agree, this thread has gone on way too long:
An truthful argument will never convince one determined to disagree.
Unknown
Danny
|
|
|
|
|
Whether
y = x + x++;
is defined was not a question. It was an example to compare with x = x++;
Now let me tell you why
y = x + x++;
is NOT defined.
Precedence and associativity of operators lead to this distribution of operands.
y = (x + (x++));
In order to evaluate operator+ the compiler has to have the results from evaluating x and x++. The compiler is free to choose the order of evaluation of these two.
Here are the cases for x = 1.
case 1: x is evaluated before x++
y = 1 + 1 = 2;
case 2: x is avaluated after x++
subcase a:
x++ evaluates to 1
x is incremented
x evaluates to 2
y = 2 + 1 = 3
subcase b:
x++ evaluates to 1
x evaluates to 1
x is incremented
y = 1 + 1 = 2
By the way
"Postfix mode causes the increment to happen after the value of the variable is used in the expression"
means the value is incremented after it is used in x++. Not after all occurances of x in the statement are evaluated.
|
|
|
|
|
You're right, pesho. I was working off of misinformation. You do know that schools and professors lies to us, right? The only thing I disagree with you is:
pesho2932 wrote:
By the way
"Postfix mode causes the increment to happen after the value of the variable is used in the expression"
means the value is incremented after it is used in x++. Not after all occurances of x in the statement are evaluated.
The quote: "Postfix mode causes the increment to happen after the value of the variable is used in the expression" does not mean that it is incremented after it is used in x++, it means it is incremented after x was used in the expression x + x . However, as I admitted in another post on this thread, the author of that book was most likely teaching about the compiler that was distributed with the book, and apparently it does not apply to all C++ code for all compilers.
However, as an aside, after participating in this thread, I believe that the action of x++ or ++x should have been defined in C++, but as an expert explained, it was "too difficult".
Danny
|
|
|
|
|
funny huh...
I believe they would say "Postfix mode causes the increment to happen after the value of the variable is used in the STATEMENT," if they meant what you suggest.
And if you find funny what I say about the order of evaluation of operands, you should revise your knowledge of sequence points.
...as should do anyone who thinks that y = x + x++; is defined by C++.
|
|
|
|
|
No, the writer would no have used the word statement. The full quote I gave in an earlier post read:
"The difference is important, however, when these operators are used in statements that do more than just incrementing or decrementing. For example, look at the following lines:
num = 4;
cout << num++;
The cout statement above is doing two things: (1) displaying the value of the num, and (2) incrementing the num. But which happens first? cout will display a different value if num is incremented first than if num is incremented last. The answer depends upon the mode of the increment operator.
Postfix mode causes the increment to happen after the value of the variable is used in the expression. In the statement above, cout will display 4 and then num will be incremented to 5."
I notice the writer does use the word statement a couple of times in that quote. The writer then goes on to explain how the postfix operator works the same in mathematical expressions. On the next page he writes, "The increment and decrement operators can also be used on variables in mathematical expressions. Consider the following program segment:
a=2;<br />
b=5;<br />
c=a*b++;<br />
cout << a << " " << b << " " << c;
In the statement c = a * b++ , c is assigned the value of a times b , which is 10. b is then incremented. The cout statement will display:
2 6 10 "
But of course this doesn't cover the case where b , for example, is used twice in the same expression. The instruction leads one to believe that in a statement, for example, such as b * b++ , that as in the above b++ would be incremented after used in the expression b * b . This is how it works on my compiler. Apparently that is not so, but you can see where this instruction, and others, would lead one to believe what I had previously assumed.
pesho2932 wrote:
And if you find funny what I say about the order of evaluation of operands, you should revise your knowledge of sequence points.
My, someone's getting touchy. By the way, weren't you the one that asked the question (well, more of a statment really) that started this thread? And now you say you know all about it?
As to your original question. You posted:
int x = 1;<br />
x = x++;
And then stated:
"I think this should be well defined.
The operations are:
1. ++
2. =
As the expression x++ is an operand of operator=, I think it should be evaluated first (??).
The final value of x should then be 1."
In your original post the question is trivial. It does not matter when x++ executed, since the increment also reassigns the incremented variable back to itself, as you noted, "But the increment seems to occur after the assignment. And x = 2." So who's the one that should revise their knowledge of C++?"
Danny
|
|
|
|
|
bugDanny wrote:
But of course this doesn't cover the case where b , for example, is used twice in the same expression
Indeed.
As an aside, in the statement cout << num++; there are four expressions: cout << num++ , cout , num , and num++ the first one conicides with the whole statement. So I don't think the writer will refer to it several times as the statement and then use the word expression for the same thing.
Here is a quotation from C++ specification:
"It is important to note that a postfix increment or decrement expression evaluates to the value of the expression prior to application of the respective operator. The increment or decrement operation occurs after the operand is evaluated. This issue arises only when the postfix increment or decrement operation occurs in the context of a larger expression."
I think, here, it is clear what is meant by "the expression."
About x = x++; I was not sure and the question was whether you agree. Now I have a better idea thanks to David Crow ("after" does not mean "immediately after"). About y = x + x++; , I had no question. It is clear to me and I gave it as an example in which the behavior is undefined.
The difference between the two is that in the first case x++ is an operand of operator= so it has to be evaluated before operator= . (But I've come to believe that evaluation of x++ can be considered complete before the increment as there is no sequence point and the result of x++ is independent of the increment. So the increment can occur before the assignment or after.)In the second one x and x++ are the two operands of operator+ so it is not known which one the compiler will choose to evaluate first. (And if it chooses to evaluate x++ first the increment will occur at some later point and may be before or after x is evaluated.)
I'm done with this topic.
|
|
|
|
|
pesho2932 wrote:
So I don't think the writer will refer to it several times as the statement and then use the word expression for the same thing.
Except, of course, in the case where x++ is used in an expression that is not a whole statement, like in, y = c + (b * x++); Here the expression that x is used in before it is incremented is obviously (b * x) .
pesho2932 wrote:
I think, here, it is clear what is meant by "the expression."
Ah, yes, "the expression" being what x++ was called in, not x++ itself, as I had noted. ("the expression prior to application of the respective operator.")
pesho2932 wrote:
I'm done with this topic.
Yes, please let the constant repeating of ourselves be over!
Danny
|
|
|
|
|
So be it.
I have no desire to explain c++ specification to you.
|
|
|
|
|
From the ASM code of VC++2003:
int x = 1;
00412F6E mov dword ptr [x],1
int y;
y = 5 + x++;
00412F75 mov eax,dword ptr [x]
00412F78 add eax,5
00412F7B mov dword ptr [y],eax
00412F7E mov ecx,dword ptr [x]
00412F81 add ecx,1
00412F84 mov dword ptr [x],ecx
printf("y = %d\n", y);
00412F87 mov eax,dword ptr [y]
00412F8A push eax
00412F8B push offset string "y = %d\n" (4240E4h)
00412F90 call @ILT+1320(_printf) (41152Dh)
00412F95 add esp,8
x = 1;
00412F98 mov dword ptr [x],1
x = y + x++;
00412F9F mov eax,dword ptr [y]
00412FA2 add eax,dword ptr [x]
00412FA5 mov dword ptr [x],eax
00412FA8 mov ecx,dword ptr [x]
00412FAB add ecx,1
00412FAE mov dword ptr [x],ecx
printf("x = %d\n", x);
00412FB1 mov eax,dword ptr [x]
00412FB4 push eax
00412FB5 push offset string "x = %d\n" (424054h)
00412FBA call @ILT+1320(_printf) (41152Dh)
00412FBF add esp,8
// Old.
int x = 1;
0041262E mov dword ptr [x],1
x = x;
00412635 mov eax,dword ptr [x]
00412638 mov dword ptr [x],eax
x++;
0041263B mov eax,dword ptr [x]
0041263E add eax,1
00412641 mov dword ptr [x],eax
x = x++;
00412644 mov eax,dword ptr [x]
00412647 mov dword ptr [x],eax
0041264A mov ecx,dword ptr [x]
0041264D add ecx,1
00412650 mov dword ptr [x],ecx
Maxwell Chen
-- modified at 22:50 Sunday 18th September, 2005
|
|
|
|
|
Maxwell Chen shows my case quite well. Thank you.
Danny
|
|
|
|
|
Dear fellow coders,
Im just trying to establish if the current user has the privileges to stop/start services.
Im trying to link some example code from the MDSN website into my visual C++ 6.0 project
and i get the following error. can you help?
Linking...
OLMECDlg.obj : error LNK2001: unresolved external symbol "int __cdecl
CheckTokenMembership(void *,void *,int *)"
(?CheckTokenMembership@@YAHPAX0PAH@Z)
Debug/OLMEC.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
the example code i was using was as follows:
#include <winbase.h>
#include <windows.h>
extern BOOL CheckTokenMembership(HANDLE TokenHandle,PSID SidToCheck,PBOOL
IsMember);
/*++
Routine Description: This routine returns TRUE if the caller's process
is a member of the Administrators local group. Caller is NOT expected
to be impersonating anyone and is expected to be able to open its own
process and process token.
Arguments: None.
Return Value:
TRUE - Caller has Administrators local group.
FALSE - Caller does not have Administrators local group. --
*/
BOOL COLMECDlg::IsUserAdmin(VOID)
{
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdministratorsGroup);
if(b)
{
if (!CheckTokenMembership( NULL, AdministratorsGroup, &b))
{
b = FALSE;
}
FreeSid(AdministratorsGroup);
}
return(b);
}
Please note that I have also setup my linker to include advapi32.lib but
this still fails. What am i doing wrong or is there a mistake on the MSDN
webpage?
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/s
ecurity/checktokenmembership.asp)
Im just trying to establish if the current user has the privileges to stop/start services.
Has anyone done this before, or know how to do it in VC6.0 ?
thanks,
Paul
|
|
|
|
|
Rainos wrote:
extern BOOL CheckTokenMembership(HANDLE TokenHandle,PSID SidToCheck,PBOOL
IsMember);
This statement is unnecessary. As long as you have included winbase.h or windows.h , the function prototype already exists.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
But if I do this - it doesnt compile! - Even with winbase.h or windows.h
Do I need to have Platform SDK or a different version of VC++ for this?
|
|
|
|
|
Rainos wrote:
But if I do this - it doesnt compile!
What compiler(s) error do you get?
Rainos wrote:
Do I need to have Platform SDK...for this
It's always a good idea to be using the latest Platform SDK (dated Feb 2003) for your development.
Rainos wrote:
Do I need to have...a different version of VC++ for this?
No, version 6 is fine.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
The compiler error is simply:
error C2065: 'CheckTokenMembership' : undeclared identifier
Dont think I have Platform SDK installed, probably just plain VC++6.0.
Ive ordered a copy of the Feb 2003 version on CD. Can it be downloaded from anywhere?
thanks,
Rainos
|
|
|
|
|
I plugged your IsUserAdmin() funnction into one of my dialog-based applications and it compiled/linked without issue.
Rainos wrote:
Can it be downloaded from anywhere?
Not any more. It was downloadable up until a few months ago.
Good luck.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
Thanks for trying that.
Im guessing you have Platform SDK installed then?
If so that confirms that I need it.
thanks,
Rainos
|
|
|
|
|
Rainos wrote:
Im guessing you have Platform SDK installed then?
That is correct.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
Hi All,
I've been working on a project that makes use of CTabCtrl in a derived class.
My problem is that when my application runs on Windows XP Themed, the background color of that tabs that should be white (?)- default - are gray as the dialogs that they are. So it causes a strange feeling... the tabs titles are white and beautiful... but the tabs contents are gray...
Does anybody already pass through this or have some idea of how can I avoid this? Maybe makes the color of my dialogs (tab contents) transparent... I just don't know
ps.: its important that works on XP Themed and other versions of Windows too.
Thanks all for the attention,
Cheers!
-- modified at 10:16 Thursday 15th September, 2005
|
|
|
|
|