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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

int main( int argc, char **argv )
{
  uint64_t n = 0x0034000000000000LLU;
  uint32_t b = n >> 32;
  uint32_t c = static_cast<uint32_t>(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<uint32_t>(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 <charl...@mcn.org> 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<unsigned long
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 <charl...@mcn.org> 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
0x0034000000000000 then

- If I compile Opt(0),NoInline then testWord gets the value I expect,
0x00340000; 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

Reply via email to