Richard Robertson Posted March 25, 2011 Posted March 25, 2011 If I had the C++ code int i = 0; i = i++; std::cout << i; What do you expect to be written?
Valik Posted March 25, 2011 Posted March 25, 2011 I... don't understand? Is this supposed to be a trick question? If so, what's the trick supposed to be? The answer should be obvious.
jvanegmond Posted March 25, 2011 Posted March 25, 2011 (edited) I'll bite! I expect 1 to be written.OMNOMNOMNOMNOMNOM Edited March 25, 2011 by Manadar github.com/jvanegmond
jaberwacky Posted March 25, 2011 Posted March 25, 2011 I would have expected 0 to be written! 0 would have been stored to i and then the value of i would have been incremented. OHH, i does store 0 and then it IS incremented afterwards! Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
Mat Posted March 25, 2011 Posted March 25, 2011 In the ideal world you get a compiler message: ERROR: User stupidity level exceeded. Unsigned 1 AutoIt Project Listing
Richard Robertson Posted March 25, 2011 Author Posted March 25, 2011 Yes I realize it's a horrible piece of code, but the fact that C++ executes the increment AFTER the assignment really confused me. I expect 0, and that's what languages like C# and Java do.
danielkza Posted March 25, 2011 Posted March 25, 2011 By the language specification changing the contents of a variable twice in the same statement is undefined behavior. Whatever happens is compiler and platform dependent.
Richard Robertson Posted March 25, 2011 Author Posted March 25, 2011 This actually started because I saw someone with that code and they wanted to know why their i variable was never incrementing because in their language, (i++) was evaluated before (i =).
Valik Posted March 25, 2011 Posted March 25, 2011 (edited) By the language specification changing the contents of a variable twice in the same statement is undefined behavior. Whatever happens is compiler and platform dependent.Source?In this case the behavior is not undefined:Assign i to the value of i (0).Increment i (1)That's how the post-increment operator works. If the code had used the pre-increment operator and been presented as i = ++i; then the sequence would become:Increment i (1)Assign i to the value of i (1).The result would not have changed. Edited March 25, 2011 by Valik
danielkza Posted March 25, 2011 Posted March 25, 2011 Source?In this case the behavior is not undefined:Assign i to the value of i (0).Increment i (1)That's how the post-increment operator works. If the code had used the pre-increment operator and been presented as i = ++i; then the sequence would become:Increment i (1)Assign i to the value of i (1).The result would not have changed.C99 Standard, Section 6.5 (Expressions), Paragraph 2:Between the previous and next sequence point an object shall have its stored valuemodified at most once by the evaluation of an expression. Furthermore, the prior valueshall be read only to determine the value to be stored.
Richard Robertson Posted March 25, 2011 Author Posted March 25, 2011 Source? In this case the behavior is not undefined: Assign i to the value of i (0).Increment i (1)That's how the post-increment operator works. If the code had used the pre-increment operator and been presented as i = ++i; then the sequence would become: Increment i (1)Assign i to the value of i (1).The result would not have changed. So you say post-increment always occurs as if it were a statement immediately after the current statement? So what do you expect from this code? int i; void f(int) { cout << i; } void main() { i = 0; f(i++); }
ProgAndy Posted March 25, 2011 Posted March 25, 2011 I think, it i will be incremented immediately after the assignment is completed. An assignment in this case is for me:1) assign to variable2) initializing the function parameter.What output do you expect here? int i; void f(int a, int <img src='http://www.autoitscript.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' /> { cout << i << " " << a << " " << b; } int main() { i = 0; f(i++, i++); } *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
Richard Robertson Posted March 25, 2011 Author Posted March 25, 2011 (edited) In the code I just posted and in your code, I would expect to see "1" and "1 1 1" respectively. My problem is that in i = i++; is that the increment happens after the statement rather than where the operator occurs. Especially since both pre- and post-increment operators are higher precedence than =. Edited March 25, 2011 by Richard Robertson
ProgAndy Posted March 25, 2011 Posted March 25, 2011 (edited) Your code outputs 1, mine outputs 2 1 0.There is another thing to try:i = i++ = i or something like that... Well if I rethink this, it won't work. Edited March 25, 2011 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
Valik Posted March 26, 2011 Posted March 26, 2011 danielkza, I'm not interested in C specifications when we are talking about C++.This is whole topic is absurd, I can't believe we are having this discussion. We're talking about the post-increment operator here. Let's stop using these stupid "i=i" examples and look at something a little less confusing:int i = 10, j = 0; j = i++; std::cout<<"j: "<<j<<", i: "<<i<<std::endl;This examples prints "j: 10, i: 11". Why? Because we used the post-increment operator. That operator works by assigning the current value of i before incrementing it. The increment happens post everything else - post-increment.int i = 10, j = 0; j = ++i; std::cout<<"j: "<<j<<", i: "<<i<<std::endl;This example prints "j: 11, i: 11". Why? Because we used the pre-increment operator. That operator works by incrementing the value of i before assigning it. The increment happens pre everything else - pre-increment.This is basic C++. There are two separate operators with different behavior. It seems people here think that the post-increment operator behaves like the pre-increment operator when it does not. Once you isolate how the operators work then it's trivial to substitute i back in for j since that part of the expression is entirely irrelevant.The pre-increment operator should be the default people use when the choice doesn't matter. Back in the day - and it could still be true - compilers optimized code better when they encountered pre-increment rather than post-increment. I imagine modern compilers have no issue with this and generate identical code except in cases where assignment is involved, but still, pre-increment is prefered. There are specific cases where you want to use the post-increment operator, however. AutoIt contains a few places where I've specifically used post-increment.TL;DR version: Learn C++.
danielkza Posted March 26, 2011 Posted March 26, 2011 (edited) @Valik:As you wish:Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expres-sions, and the order in which side effects take place, is unspecified. Between the previous and next sequence point ascalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the priorvalue shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met foreach allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefinedI understood that the specific case of assigning to and incrementing a variable in the same statement was the topic in discussion. That's what I was talking about. In respect to it, pre or post-increment is irrelevant: in both cases the behavior would be undefined because i would be modified twice before a sequence point. In theory it would be possible to write down some rules that would make sense of the code in the OP, but the spec omits them purposely in favor of freedom of implementation. The compiler is free to delay committing of variables to their storage (usually RAM) until a sequence point occurs, and that's why you can't be sure the increment will actually happen before or after the assignment. Edited March 26, 2011 by danielkza Unsigned 1
Valik Posted March 26, 2011 Posted March 26, 2011 According to Wikipedia (for what that's worth), you are correct - barely. I was under the impression that operators had function semantics even when not overloaded. Functions are sequence points. However, an operator only behaves like a function (and acts a sequence point) if it's overloaded. In this case, since the operators are not overloaded, it is undefined behavior. Unsigned 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now