Re: Looking for help with an obscure C integer problem
When performing integer (not int) arithmetic with integer operands of rank lower than int, the operands will be promoted to either int or unsigned int. When adding two short or two char or a char and a short, both operands will be promoted to int before the addition and the result will be an int. When any operand is of rank greater or equal to int, all operands are promoted to the highest rank in the expression and the arithmetic is performed on that type. Operands of rank greater than int are not demoted to int. The expression in question involves shifting an unsigned long long and the result will be an unsigned long long. When the result is assigned to the left operand, it will be converted to the type of that operand. This is true regardless of the type of the left operand. - Original Message - From: "Bernd Oppolzer" To: IBM-MAIN@LISTSERV.UA.EDU Sent: Monday, July 22, 2013 12:18:25 PM Subject: Re: Looking for help with an obscure C integer problem That is another case, because the right side operands are not ints. For ints, I saw references that all operands are promoted to ints, if they can be represented as an int (that is true for chars, shorts etc.). Don't know for sure about longs, for example; if long differs in size from int, and there are longs on the right side, will they be promoted (that is: truncated) to int, if there is an int on the left side, or will they be evaluated as longs? That's the key question IMHO, and there should be a reference in the C language description that makes it clear without doubt - but I did not yet find such a reference - had not much time to look for it. (IMO, it would be no good language design if such a core question is left to the compiler builder - I don't believe it is so). Kind regards Bernd Am 22.07.2013 18:27, schrieb retired-mainfra...@q.com: > The right operand in this case is the result of evaluating the expression. > The quoted text is not meant to imply that operands are converted before the > right hand expression is evaluated. If that were the case, then > int x = 14.0/2.1; > would evaluate to 7 which is demonstrably not the case. > -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: Looking for help with an obscure C integer problem
The right operand in this case is the result of evaluating the expression. The quoted text is not meant to imply that operands are converted before the right hand expression is evaluated. If that were the case, then int x = 14.0/2.1; would evaluate to 7 which is demonstrably not the case. - Original Message - From: "Charles Mills" To: IBM-MAIN@LISTSERV.UA.EDU Sent: Sunday, July 21, 2013 1:26:54 PM Subject: Re: Looking for help with an obscure C integer problem You are 100% correct. You nailed it. Stroustrup p. 263: "If both operands have arithmetic type, the right operand is converted to the type of the left preparatory to the assignment." That explains why it fails, but not why it works Opt(0). I am going to *guess* that Opt(0) it compiles as though I had coded testWord = static_cast(valueToTest >> 32) while with Opt(2) it compiles as though I had coded testWord = static_cast(valueToTest) >> 32; In your earlier post you suggested "wasting" another long long. Yes, that's an approach. Actually I am finished with valueToTest and can just do things in two steps without "wasting" a variable: valueToTest >>= 32; testWord = valueToTest; I am busy with other things perhaps until sometime this week but the first thing I am going to try is simply using parentheses to attempt to "force" the "Opt(0)" interpretation: testWord = (valueToTest >> 32); If that fails I will move on to more elaborate approaches. The "two statement" approach will either work or else it is a very clear bug and I will re-group. Will probably try the union approach at that point. Thanks! Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of Bernd Oppolzer Sent: Sunday, July 21, 2013 9:44 AM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: Looking for help with an obscure C integer problem BTW: I think I remember from an old book on C programming: "if the target of an assignment is int, all operands on the right side are converted to int - if the target of an assignment is long, all operands on the right side are converted to long" If I remember correctly, this would perfectly explain the behaviour you see (of course, it makes more sense for data types being shorter than the type of the assignment target, but if it's done as written above, you have it for longer types, too). Kind regards Bernd Am 21.07.2013 18:32, schrieb Bernd Oppolzer: > Sorry for jumping late into this thread. > > Why not spend another variable of type long long to do the shift there? > > like > > unsigned long long valueToTest; > unsigned int testWord; > unsigned long long x; > > x = valueToTest >> 32; /* here */ > testWord = (int) x; -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: Looking for help with an obscure C integer problem
You remember incorrectly. The expr4essions of the right are evaluated accoriding to the "normal rules". Only the final result is coerced into the type of the left operand. - Original Message - From: "Bernd Oppolzer" To: IBM-MAIN@LISTSERV.UA.EDU Sent: Sunday, July 21, 2013 11:44:11 AM Subject: Re: Looking for help with an obscure C integer problem BTW: I think I remember from an old book on C programming: "if the target of an assignment is int, all operands on the right side are converted to int - if the target of an assignment is long, all operands on the right side are converted to long" If I remember correctly, this would perfectly explain the behaviour you see (of course, it makes more sense for data types being shorter than the type of the assignment target, but if it's done as written above, you have it for longer types, too). Kind regards Bernd Am 21.07.2013 18:32, schrieb Bernd Oppolzer: > Sorry for jumping late into this thread. > > Why not spend another variable of type long long to do the shift there? > > like > > unsigned long long valueToTest; > unsigned int testWord; > unsigned long long x; > > x = valueToTest >> 32; /* here */ > testWord = (int) x; > > > If now in the expression marked with /* here */ the compiler > does not do the shift as a true 64 bit shift, there is no excuse > and you should report this as a bug. The cast to int is done > in the next statement. > > In the other case there may be some strange language rules > that allow the long long variable to be casted to int before the > shift - I don't know, but why lose time and think much about it? > > Kind regards > > Bernd > > > > > Am 20.07.2013 22:24, schrieb Charles Mills: >> Cross-posted to IBM-MAIN and MVS-OE. >> >> I have the following code fragment in an inline function, compiled by >> the >> IBM XLC compiler as C++: >> >> unsigned long long valueToTest; >> unsigned int testWord; >> testWord = valueToTest >> 32; >> >> It *appears* to me (from somewhat circumstantial evidence in a much more >> complex big picture) when valueToTest has a value of >> 0x0034 then >> >> - If I compile Opt(0),NoInline then testWord gets the value I expect, >> 0x0034; but >> - If I compile Opt(2),Inline then testWord gets a value of 0. >> >> Questions: >> >> 1. Does that seem plausible? That the code would work as intended >> Opt(0),NoInline but that with Opt(2),Inline the compiler would (I am >> guessing here) first cast valueToTest to an int of 0, then shift it >> right >> 32, and then assign it to testWord? >> >> 2. What should I code to avoid that? I guess I could shift >> valueToTest first >> (I don't need it again) and then in a separate statement assign it to >> testWord. Is that the "proper" coding technique? >> >> It's fairly involved to test the whole thing so I took the liberty of >> imposing on you folks rather than just trying stuff. Thanks much. >> >> Charles >> >> -- >> For IBM-MAIN subscribe / signoff / archive access instructions, >> send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN >> > > -- > For IBM-MAIN subscribe / signoff / archive access instructions, > send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN > -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: [MVS-OE] Looking for help with an obscure C integer problem
Since the evaluated expression is automatically converted to the type of the left operand aspart of the assignment process, what purpose does the cast serve? - Original Message - From: "David Crayford" To: IBM-MAIN@LISTSERV.UA.EDU Sent: Saturday, July 20, 2013 8:06:37 PM Subject: Re: [MVS-OE] Looking for help with an obscure C integer problem Your casting a uint64_t to a uint64_t which is pointless. You should cast to the return value (uint32_t). I've just tried your example and I can't recreate the problem, with or without casts and compiled with both OPT and NOOPT. #include #include #include #include int main( int argc, char **argv ) { uint64_t n = 0x0034LLU; uint32_t b = n >> 32; uint32_t c = static_cast(n >> 32); printf( "%08X %08X\n", b, c ); } I can only assume that the optimizer is throwing away valueToTest for some arcane reason. I've seen this happen with convoluted code with lots of pointers to pointers etc. Try qualifying valueToTest with volatile, which should disable optimizations on that variable. On 21/07/2013 8:27 AM, Charles Mills wrote: > Hmmm. Not following your logic but I may give it a try. > > Charles > > -Original Message- > From: MVS OpenEdition [mailto:mvs...@vm.marist.edu] On Behalf Of David > Crayford > Sent: Saturday, July 20, 2013 4:51 PM > To: mvs...@vm.marist.edu > Subject: Re: [MVS-OE] Looking for help with an obscure C integer problem > > If static_cast(valueToTest >> 32) doesn't fix it then the compiler > is broken. Note the cast to uint32_t not uint64_t. > > On 21/07/2013, at 6:36 AM, Charles Mills wrote: > >> Thanks. How would I solve this with a cast? I can force it to be wrong >> LOL but can I force it to be right? >> >> It seems to me like testWord = static_cast> long>(valueToTest 32) might not solve the problem because that cast seems to me to imply >> that the expression inside the parentheses is *not* 64 bits. >> >> Frankly, I am now leaning toward >> >> union { >> unsigned long long ll; >> struct {unsigned int hi; unsigned int lo} s; } u; >> >> u.ll = valueToTest; >> >> and then using u.s.hi where I now use testWord. >> >> I generally avoid unions because they can be a tad problematic. I >> think the above actually violates the C standard which says you can't >> assign to member x and then read member y (which pretty much negates >> the whole purpose of unions other than, as Stroustrup suggests, saving > space in memory). >> Charles >> >> -Original Message- >> From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] >> On Behalf Of David Crayford >> Sent: Saturday, July 20, 2013 2:28 PM >> To: IBM-MAIN@LISTSERV.UA.EDU >> Subject: Re: Looking for help with an obscure C integer problem >> >> As a general ROT I always use explicit casts. >> >> On 21/07/2013, at 4:24 AM, Charles Mills wrote: >> >>> Cross-posted to IBM-MAIN and MVS-OE. >>> >>> I have the following code fragment in an inline function, compiled by >>> the IBM XLC compiler as C++: >>> >>> unsigned long long valueToTest; >>> unsigned int testWord; >>> testWord = valueToTest >> 32; >>> >>> It *appears* to me (from somewhat circumstantial evidence in a much >>> more complex big picture) when valueToTest has a value of >>> 0x0034 then >>> >>> - If I compile Opt(0),NoInline then testWord gets the value I expect, >>> 0x0034; but >>> - If I compile Opt(2),Inline then testWord gets a value of 0. >>> >>> Questions: >>> >>> 1. Does that seem plausible? That the code would work as intended >>> Opt(0),NoInline but that with Opt(2),Inline the compiler would (I am >>> guessing here) first cast valueToTest to an int of 0, then shift it >>> right 32, and then assign it to testWord? >>> >>> 2. What should I code to avoid that? I guess I could shift >>> valueToTest first (I don't need it again) and then in a separate >>> statement assign it to testWord. Is that the "proper" coding technique? > -- > For IBM-MAIN subscribe / signoff / archive access instructions, > send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: Looking for help with an obscure C integer problem
Are you coding in C or C++? static_cast is a C++ feature. - Original Message - From: "Charles Mills" To: IBM-MAIN@LISTSERV.UA.EDU Sent: Saturday, July 20, 2013 5:36:01 PM Subject: Re: Looking for help with an obscure C integer problem Thanks. How would I solve this with a cast? I can force it to be wrong LOL but can I force it to be right? It seems to me like testWord = static_cast(valueToTest >> 32) might not solve the problem because that cast seems to me to imply that the expression inside the parentheses is *not* 64 bits. Frankly, I am now leaning toward union { unsigned long long ll; struct {unsigned int hi; unsigned int lo} s; } u; u.ll = valueToTest; and then using u.s.hi where I now use testWord. I generally avoid unions because they can be a tad problematic. I think the above actually violates the C standard which says you can't assign to member x and then read member y (which pretty much negates the whole purpose of unions other than, as Stroustrup suggests, saving space in memory). Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of David Crayford Sent: Saturday, July 20, 2013 2:28 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: Looking for help with an obscure C integer problem As a general ROT I always use explicit casts. On 21/07/2013, at 4:24 AM, Charles Mills wrote: > Cross-posted to IBM-MAIN and MVS-OE. > > I have the following code fragment in an inline function, compiled by > the IBM XLC compiler as C++: > > unsigned long long valueToTest; > unsigned int testWord; > testWord = valueToTest >> 32; > > It *appears* to me (from somewhat circumstantial evidence in a much > more complex big picture) when valueToTest has a value of > 0x0034 then > > - If I compile Opt(0),NoInline then testWord gets the value I expect, > 0x0034; but > - If I compile Opt(2),Inline then testWord gets a value of 0. > > Questions: > > 1. Does that seem plausible? That the code would work as intended > Opt(0),NoInline but that with Opt(2),Inline the compiler would (I am > guessing here) first cast valueToTest to an int of 0, then shift it > right 32, and then assign it to testWord? > > 2. What should I code to avoid that? I guess I could shift valueToTest > first (I don't need it again) and then in a separate statement assign > it to testWord. Is that the "proper" coding technique? > > It's fairly involved to test the whole thing so I took the liberty of > imposing on you folks rather than just trying stuff. Thanks much. > > Charles > > -- > For IBM-MAIN subscribe / signoff / archive access instructions, send > email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: Storage utililzation Optimization
Whatever "solution" you decide upon, make very sure (as in well tested) you have recoverable copies of any datasets or files you remove from DASD. - Original Message - From: "mfstorage" To: IBM-MAIN@LISTSERV.UA.EDU Sent: Saturday, July 21, 2012 6:54:13 AM Subject: Storage utililzation Optimization Hi, In our ever expanding Storage needs...my management has tasked me to review the storage we are using and targeted a reduction of 10-15% of it by doing necessary cleanup. Can someone suggest the best practices i could follow to achieve this. Thanks, Rahul -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN