- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could that be because those suffixes are reserved for constant integer types declaration and can not be used in the macro declaration.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>...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'?"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>...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';
...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>>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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for all your comments!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page