When you really really really want a UInt32



  • This is the real deal folks. They are serious about needing that unsigned 32-bit integer, and nothing else, under any circumstances. There is absolutely no room for error here.

    UInt32 LANG_SYSTEM_DEFAULT = ((((UInt32)(0x01)) << 10) | (UInt32)(0x00));
    UInt32 LOCALE_SYSTEM_DEFAULT = ((UInt32)((((UInt32)((UInt32)(0x0))) << 16) | ((UInt32)((UInt32)(LANG_SYSTEM_DEFAULT)))));
    

    Wow.



  • I know some people have trouble with casting and sometimes (no pun intended) "overcast", but this... there are no words to describe this.



  • To be fair, I figured out what was going on. They had converted some preprocessor macros into C# directly with some other #define'd values substituted.



  • <font face="courier new,courier">#define UInt32 char</font>



  • This isnt all that far off-- the constants will default to ints, which may be too narrow to tolerate all that left shifting.

     one WTF is all the careful  left-shifting of 0x0.



  • @Ancient_Hacker said:

    This isnt all that far off-- the constants will default to ints, which may be too narrow to tolerate all that left shifting.

    one WTF is all the careful left-shifting of 0x0.

    This is why you use unsigned long constants

    UInt32 LANG_SYSTEM_DEFAULT = (((0x01UL) << 10) | 0UL);
    UInt32 LOCALE_SYSTEM_DEFAULT = ((UInt32)((0UL << 16) | (UInt32)(LANG_SYSTEM_DEFAULT)));


  • @Random832 said:

    @Ancient_Hacker said:

    This isnt all that far off-- the constants will default to ints, which may be too narrow to tolerate all that left shifting.

    one WTF is all the careful left-shifting of 0x0.

    This is why you use unsigned long constants

    UInt32 LANG_SYSTEM_DEFAULT = (((0x01UL) << 10) | 0UL);
    UInt32 LOCALE_SYSTEM_DEFAULT = ((UInt32)((0UL << 16) | (UInt32)(LANG_SYSTEM_DEFAULT)));

    This is still a major WTF. Why would you OR 1024 with zero, store it in a variable, then OR that variable with zero << 16, and store that resulting same number in a variable?



  • Well, we're clearly looking at generated code, so you can't say that these are always going to be 1, 10, 0, and 16.



  • @Random832 said:

    Well, we're clearly looking at generated code, so you can't say that these are always going to be 1, 10, 0, and 16.

    No, this was done by hand. They've put the macros that these lines come from in comments near one instance of this code (it shows up twice, actually). These are local variables in a method we're looking at here, not a utility class with constants generated by a tool.



  • Surely: 

    UInt32 LANG_SYSTEM_DEFAULT = 1024;

    UInt32 LOCALE_SYSTEM_DEFAULT = LANG_SYSTEM_DEFAULT;
    Or is there some kind of weird bitshifting magic going on in here where doing 0<<16 actually has a point?
    When casting between primitives, I always preferred using this syntax:
    UInt32 myNumber = UInt32(0x1 << 10) | UInt32(0x8);
    Since all the brackets make my eyes bleed, though I've no idea if this is supported in C#... 
     


  • ^^^^^^^^^^^

    I have no idea why that happened o_O 



  • @djork said:

    @Random832 said:
    Well, we're clearly looking at generated code, so you can't say that these are always going to be 1, 10, 0, and 16.

    No, this was done by hand. They've put the macros that these lines come from in comments near one instance of this code (it shows up twice, actually). These are local variables in a method we're looking at here, not a utility class with constants generated by a tool.


    Are you _sure_ they didn't have a tool that A) expands macros and B) puts comments next to each line it touches? (or even they placed the comments for clarity after seeing how the output from their tool looks, but not knowing how to simplify it)


  • @Random832 said:

    @djork said:
    @Random832 said:
    Well, we're clearly looking at generated code, so you can't say that these are always going to be 1, 10, 0, and 16.

    No, this was done by hand. They've put the macros that these lines come from in comments near one instance of this code (it shows up twice, actually). These are local variables in a method we're looking at here, not a utility class with constants generated by a tool.


    Are you _sure_ they didn't have a tool that A) expands macros and B) puts comments next to each line it touches? (or even they placed the comments for clarity after seeing how the output from their tool looks, but not knowing how to simplify it)

    As far as I know no such thing exists. And, like I said, this is in the body of a method... these are local variables... not some utility class with a bunch of static/const fields. No tool worth its salt would expand macros like that. But now that I think about it... someone should make this tool :)



  • @djork said:

    As far as I know no such thing exists. And, like I said, this is in the body of a method... these are local variables... not some utility class with a bunch of static/const fields. No tool worth its salt would expand macros like that. But now that I think about it... someone should make this tool :)

    Someone did, other than the part about putting comments on lines it's changed (though it does add something like comments to fix up line numbering where it changes that) I think you might not quite understand what a macro is. 



  • @Random832 said:

    @djork said:

    As far as I know no such thing exists. And, like I said, this is in the
    body of a method... these are local variables... not some utility class
    with a bunch of static/const fields. No tool worth its salt would
    expand macros like that. But now that I think about it... someone
    should make this tool :)

    Someone did, other than the part about putting comments on lines it's changed (though it does add something like comments to fix up line numbering where it changes that) I think you might not quite understand what a macro is. 

    I understand how preprocessor macros work. Running cpp on C source does not typically result in C# code. If they used the preprocessor to expand the macros, they still had to take the output and substitute the C# equivalents (UInt32) in. At that point they should have realized that they were making 7 unnecessary casts, shifting zero, and OR'ing with zero twice.



  • Unless they did a global find and replace of the data types.



  • @djork said:

    @Random832 said:

    @djork said:

    As far as I know no such thing exists. And, like I said, this is in the
    body of a method... these are local variables... not some utility class
    with a bunch of static/const fields. No tool worth its salt would
    expand macros like that. But now that I think about it... someone
    should make this tool :)

    Someone did, other than the part about putting comments on lines it's changed (though it does add something like comments to fix up line numbering where it changes that) I think you might not quite understand what a macro is. 

    I understand how preprocessor macros work. Running cpp on C source does not typically result in C# code.

    No, but you're free to run cpp on C# code. GNU cpp purports to be language-agnostic, and C#'s lexer is similar enough to C's that there won't be any _horribly_ bad problems (other than the WTF of using cpp, especially on a language other than C, C++, or (oddly enough) Xdefaults, in the first place)

    But, regardless of whether it's cpp, m4, or some other implementation, why should a macro care whether it's in a method body, a utility class, or the top level? That's why it's a macro.

    At that point they should have realized that they were making 7 unnecessary casts, shifting zero, and OR'ing with zero twice.

    Even if they did, they might have assumed "well, this must be here for a reason, better not mess with it"



  • @djork said:

    @Random832 said:
    Well, we're clearly looking at generated code, so you can't say that these are always going to be 1, 10, 0, and 16.

    No, this was done by hand. They've put the macros that these lines come from in comments near one instance of this code (it shows up twice, actually). These are local variables in a method we're looking at here, not a utility class with constants generated by a tool.

    This is an obvious macro expansion of the Win32 locale functions in the way they're commonly used (and ported to C#).  Here is the original C++, for your viewing pleasure:

    LCID LOCALE_SYSTEM_DEFAULT = MAKELCID(MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_NEUTRAL), SORT_DEFAULT);

    LCID is a DWORD (uint32).  I see no reason to mess with it, despite of how ugly it is.
     


Log in to reply