Community
cancel
Showing results for 
Search instead for 
Did you mean: 
SKost
Valued Contributor II
806 Views

Macro wrappers around L, UL, LL, ULL, i64 and ui64 suffixes for 32-bit and 64-bit constants

It looks like impossible to create macro wrappers around L, UL, LL, ULL, i64 and ui64 suffixes for 32-bit and 64-bit constants. If you declare a macro as follows: ... #define _ULL ULL ... and then use it: ... unsigned __int64 ui64ValueULL = 4_ULL; ... you could get a compilation error 'Bad suffix on number', or similar. It is a problem when different C/C++ compilers are used to compile sources for different 16-bit ( embedded ), 32-bit ( desktop / embedded ) and 64-bit ( desktop ) platforms. I see that the best solution in case of highly portable C/C++ codes is Do Not Use L, UL, LL, ULL, i64 and ui64 at all. Here is a simple test-case: #if ( defined ( _WIN32_ICC ) || defined ( _WIN32_MSC ) || defined ( _WIN32CE_MSC ) ) _int32 i32ValueL = 1L; unsigned __int32 ui32ValueUL = 2UL; __int64 i64ValueLL = 3LL; unsigned __int64 ui64ValueULL = 4ULL; __int64 i64Valuei64 = 5i64; unsigned __int64 ui64Valueui64 = 6ui64; #endif #if ( defined ( _WIN32_MGW ) ) __int32 i32ValueL = 1L; unsigned __int32 ui32ValueUL = 2UL; __int64 i64ValueLL = 3LL; unsigned __int64 ui64ValueULL = 4ULL; __int64 i64Valuei64 = 5; // Doesn't support i64 suffix ( a compilation error ) unsigned __int64 ui64Valueui64 = 6; // Doesn't support ui64 suffix ( a compilation error ) #endif #if ( defined ( _WIN32_BCC ) ) __int32 i32ValueL = 1L; unsigned __int32 ui32ValueUL = 2UL; __int64 i64ValueLL = 3; // Doesn't support LL suffix ( a compilation error ) unsigned __int64 ui64ValueULL = 4; // Doesn't support ULL suffix ( a compilation error ) __int64 i64Valuei64 = 5i64; unsigned __int64 ui64Valueui64 = 6ui64; #endif #if ( defined ( _COS16_TCC ) ) __int32 i32ValueL = 1L; unsigned __int32 ui32ValueUL = 2UL; __int64 i64ValueLL = 3; // Doesn't support LL suffix ( a compilation error ) unsigned __int64 ui64ValueULL = 4; // Doesn't support ULL suffix ( a compilation error ) __int64 i64Valuei64 = 5; // Doesn't support i64 suffix ( a compilation error ) unsigned __int64 ui64Valueui64 = 6; // Doesn't support ui64 suffix ( a compilation error ) #endif and absolutely postable solution is: ... __nt32 i32ValueL = 1; unsigned __int32 ui32ValueUL = 2; __int64 i64ValueLL = 3; unsigned __int64 ui64ValueULL = 4; __int64 i64Valuei64 = 5; unsigned __int64 ui64Valueui64 = 6; ... Any comments?
0 Kudos
8 Replies
Bernard
Black Belt
806 Views

Could that be because those suffixes are reserved for constant integer types declaration and can not be used in the macro declaration.
jimdempseyatthecove
Black Belt
806 Views

Most compilers should promote the constant initializer (expression). Of bigger issue is the inconsistancy of integer of specific width i.e. what is int vs long or __int32, _int32_t, int32_t, etc... For constant expressions consider a cast of constructor (if C++) T foo = (T)123; T foo = T(123); Jim Dempsey
SKost
Valued Contributor II
806 Views

>>...Of bigger issue is the inconsistancy of integer of specific width i.e. what is int vs long... This is a good example and I saw this so many times on different projects. Every time I was asking a question: "Why do you need to declare a variable as 'long'? Could you be more specific and declare the variable as some 'int'?"
SKost
Valued Contributor II
806 Views

>>...Could that be because those suffixes are reserved for constant integer types declaration and can not be used in the macro >>declaration. Yes and this is what I was able to see today. It gets even worse for L because in a UNICODE environment it is used as a Character Constant: ... wchar_t wcText[] = L'abc'; ...
Bernard
Black Belt
806 Views

>>>Yes and this is what I was able to see today. It gets even worse for L because in a UNICODE environment it is used as a Character Constant:>>> It does not surprise me.Those letters in variuos programming "contexts" have various meaning.Probably at the parser stage those keywords are interpreted as UNICODE charcters and later from the whole sentence context the proper meaning is deducted. I think that in your first case those suffixes are treated as a reserved keywords and checked for it already at the preprocessor stage.
Georg_Z_Intel
Employee
806 Views

Hello Sergey, the answer to your initial problem is that parts of identifiers cannot be substituted by macros. In your example 4_ULL is treated as a single identifier at the preprocessing stage (even though it doesn't make sense semantically). Please note that "_" (underscore) is a valid part of an identifier and not a delimiter. Best regards, Georg Zitzlsberger
SKost
Valued Contributor II
806 Views

Thanks for all your comments!
jimdempseyatthecove
Black Belt
806 Views

int, long, ..._L, ..._UL... all should be avoided when specific numerical size is required. This is not to say these should never be used, rather it is to say do not rely on a particular number of bits, or minimum number of bits. Unfortunately for us programmers, there is no standardized naming convention amongst all compiler vendors. Jim Dempsey