Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

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

SergeyKostrov
Valued Contributor II
2,770 Views
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
Valued Contributor I
2,770 Views
Could that be because those suffixes are reserved for constant integer types declaration and can not be used in the macro declaration.
0 Kudos
jimdempseyatthecove
Honored Contributor III
2,770 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
0 Kudos
SergeyKostrov
Valued Contributor II
2,770 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'?"
0 Kudos
SergeyKostrov
Valued Contributor II
2,770 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'; ...
0 Kudos
Bernard
Valued Contributor I
2,770 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.
0 Kudos
Georg_Z_Intel
Employee
2,770 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
0 Kudos
SergeyKostrov
Valued Contributor II
2,770 Views
Thanks for all your comments!
0 Kudos
jimdempseyatthecove
Honored Contributor III
2,770 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
0 Kudos
Reply