-1

I'm at a complete loss! Why does my code not work as expected? I have the following code:

UINT64 tmpA = 0;
UINT64 tmpB = 0; 
UINT64 alarmed_lans = 0;
int foprtmsk[2]={0};
switch_fo_prtmsk_getptr(foprtmsk); 
tmpA = foprtmsk[1];                            
tmpB = foprtmsk[0];                            
gDbgLog("tmpA <%016llx>",tmpA);                
gDbgLog("tmpB <%016llx>",tmpB);                
gDbgLog("alarmed_lans <%016llx>",alarmed_lans);
alarmed_lans &= ((tmpA<<32) |tmpB);            
gDbgLog("alarmed_lans <%016llx>",alarmed_lans);

and the log produced looks like:

|0x1f604|7857[us]|fpga-alarm|fpga_faultlocalizer|tmpA <ffffffffeffeffff>
|0x1f6cb|7861[us]|fpga-alarm|fpga_faultlocalizer|tmpB <ffffffffffffffff>
|0x1f741|7863[us]|fpga-alarm|fpga_faultlocalizer|alarmed_lans <3003000000000000>
|0x1f7b8|7865[us]|fpga-alarm|fpga_faultlocalizer|alarmed_lans <3003000000000000>

Now, I'm wondering, why does the bitmask not get applied properly??? I'd expect to see

|0x1f7b8|7865[us]|fpga-alarm|fpga_faultlocalizer|alarmed_lans <2002000000000000>

What's going on here?

CPU: PPC85XXe500
compiler: diab
OS: VxWorks

stdcerr
  • 13,725
  • 25
  • 71
  • 128
  • 4
    You never initialized `alarmed_lans` so your program causes undefined behaviour – M.M Jun 30 '17 at 01:49
  • And don't use homebrew types if there are standard types. Use `uint64_t`, etc. – too honest for this site Jun 30 '17 at 01:50
  • @M.M Sorry, I missed that, it actually gets initialized to 0, I fixed this now – stdcerr Jun 30 '17 at 01:53
  • 4
    You fixed `alarmed_lans` not being initialized, but now it makes even less sense. Where does `alarmed_lans` get set to `3003000000000000`? – Mike Holt Jun 30 '17 at 01:55
  • @Olaf There is `UINT64` is defined as follows: `typedef uint64_t UINT64;` What speaks against usage of this? – stdcerr Jun 30 '17 at 01:56
  • 1
    @cerr: Which added benefit does it have compared to using the standard alias? Note that in C one cannot define new types (my comment was a bit imprecise). Another aspect is that all-uppercase is commonly used for macros and _enum-constants_ only. This is one of the few well accepted naming conventions. Concentrate on writing readable code. – too honest for this site Jun 30 '17 at 01:59
  • @Olaf `struct` can be used to define new types in C – M.M Jun 30 '17 at 02:12
  • @M.M: A _struct (or union) specifier_ does not create a new type, Two identical such specifiers denote the same type ("compatible types"). And `typedef` as used here is just syntactic sugar, defining an alias for a type. – too honest for this site Jun 30 '17 at 11:53
  • Yeah... the same new type. `struct S { int x, y; };` makes a new type `struct S` that did not previously exist. – M.M Jun 30 '17 at 12:00
  • @Olaf part of writing readable code is also to align with the conventions used in different places of the application, is it not? These `typedefs` weren't added by me and they're used all over the application. – stdcerr Jun 30 '17 at 16:20
  • 1
    @cerr: Yes. And it only should use custom conventions if there are no standard or well accepted conventions. That's all my comment says. If your application uses such homebrew aliases, it is badly designed. Not the first one I see and most likely not the last. But maybe pointing that out might avoid one bad coded program. – too honest for this site Jun 30 '17 at 17:43
  • @olaf UINT64 is the standard (little s) definition used in vxworks, which may well (and often is) being compiled without access to the stdint types. UINT64 _is_ the standard and well accepted convention used in this environment – mjs Jul 03 '17 at 20:39
  • @mjs: If it is standard, please provide a reference to the standard document. Otherwise it might be common in vxworks, but it is not standard. Considering the age of that OS, it was clear it is some legacy stuff. – too honest for this site Jul 03 '17 at 20:42
  • @Olaf hence standard with a little s, meaning convention – mjs Jul 03 '17 at 21:15
  • @mjs: "standard" is always written with lower `s` in English. What you mean is a norm. - If you are a native German speaker: they are perfect false friends. – too honest for this site Jul 04 '17 at 01:20

2 Answers2

1
alarmed_lans &= ((tmpA<<32) |tmpB);
  • alarmed_lans was never initialised. Using it results in undefined behaviour.
    • tmpB is 0xfffff… (all 1s)
    • OR that with anything and you get all 1s again.
    • AND that with x and you get x

In theory, you should get the uninitialised value of alarmed_lans, but in practice, the compiler is allowed to do anything, including the invocation of nasal demons

Baldrickk
  • 4,291
  • 1
  • 15
  • 27
1
alarmed_lans &= ((tmpA << 32) | tmpB);
                              ^            // change this | to &
alarmed_lans &= ((tmpA << 32) & tmpB);
nglee
  • 1,913
  • 9
  • 32