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

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?

9 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.
Portrait de iliyapolak

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

Portrait de jimdempseyatthecove

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

www.quickthreadprogramming.com

>>...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'?"

>>...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';
...

Portrait de iliyapolak

>>>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.

Portrait de Georg Zitzlsberger (Intel)

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

Thanks for all your comments!

Portrait de jimdempseyatthecove

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

www.quickthreadprogramming.com

Connectez-vous pour laisser un commentaire.