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

Should my intel C++ compiler (intel64) be setting _M_X64 ?

Bernhard_S_
Beginner
1,443 Views

Hello,

I had some trouble compiling some opens-ource code with the intel C++ compiler (version 13.0.1 20121010, intel64 architecture). The code contained the following directives:

----------

#if defined(UTK__C_Intel) || defined(UTK__C_MSVC)
  #if defined(_M_IX86)
    #define UTK__Arch_Intel_x86
  #elif defined(_M_X64) || defined(_M_AMD64)
    #define UTK__Arch_AMD64
  #elif defined(_M_PPC)
    #define UTK__Arch_PowerPC
  #elif defined(_M_IA64)
    #define UTK__Arch_Itanium
  #elif defined(_M_MRX000)
    #define UTK__Arch_MIPS
  #else
    #error Architecture not supported.
  #endif
------------

The error "Architecture not supported" as triggered. Shoulkdn't  _M_X64 be defined by the compiler?

Thank you for your help.

0 Kudos
13 Replies
Georg_Z_Intel
Employee
1,443 Views
Hello, the _M_X64 macro is only defined for the Windows* version of our compiler. Have you used it on Linux* or Mac OS*? It's not supported there. Solution: Use __x86_64 or _LP64 instead. Best regards, Georg Zitzlsberger
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
>>...Shouldn't _M_X64 be defined by the compiler? It has to be defined if the code is compiled for Intel CPUs. When verifying support for different platforms in a case for 64-bit platform on Intel CPU I discovered that a macro _M_AMD64 defined as well and this is how that piece of codes looks like: #if defined ( _M_IX86 ) #pragma message ( "*** Message: Compiling for Intel Processing Unit ( 32-bit ) ***" ) #endif #if defined ( _M_IA64 ) #pragma message ( "*** Message: Compiling for Intel Processing Unit ( 64-bit Itanium ) ***" ) #endif #if defined ( _M_X64 ) #pragma message ( "*** Message: Compiling for Intel Processing Unit ( 64-bit ) ***" ) #endif #if defined ( _M_AMD64 ) #pragma message ( "*** Message: Compiling for AMD Processing Unit ( 64-bit ) ***" ) #endif #if defined ( _M_ARM ) #pragma message ( "*** Message: Compiling for ARM Processing Unit ***" ) #endif #if defined ( _M_SH ) #pragma message ( "*** Message: Compiling for SH Processing Unit ***" ) #endif #if defined ( _M_MRX000 ) #pragma message ( "*** Message: Compiling for Mips Processing Unit ***" ) #endif #if defined ( _M_ALPHA ) #pragma message ( "*** Message: Compiling for Alpha Processing Unit ***" ) #endif #if defined ( _M_PPC ) #pragma message ( "*** Message: Compiling for PowerPc Processing Unit ***" ) #endif #if defined ( _M_M68K ) #pragma message ( "*** Message: Compiling for Motorola Processing Unit ***" ) #endif It is not clear for me why _M_AMD64 macro is also defined. I asked about it on some forum long time ago and had no clear answer.
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
For example, here is a compiler's output: ... ------ Build started: Project: MemTestApp, Configuration: Release x64 ------ Compiling... Stdafx.cpp Compiling... MemTestApp.cpp *** Message: Compiling for Intel Processing Unit ( 64-bit ) *** *** Message: Compiling for AMD Processing Unit ( 64-bit ) *** Linking... Generating code Finished generating code Embedding manifest... MemTestApp - 0 error(s), 0 warning(s) ... I also know that a 64-bit version of 'MemTestApp' will work on Intel and AMD CPUs and I verified it a couple of months ago.
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
Hi Georg, >>...the _M_X64 macro is only defined for the Windows* version of our compiler... This is what MSDN says about a pre-defined ANSI macro _M_X64: ... _M_X64 - Defined for x64 processors ... My understanding is as follows: if some project is compiled for a 64-bit platform then _M_X64 has to be defined. If Intel C++ compiler defines the macro on a 64-bit WIndows platform and doesn't define the macro on 64-bit Linux or Mac platforms it doesn't look right because all macros with a prefix '_M_' are ANSI pre-defined macros. I gave you a complete set of '_M_'-like macros. I didn't have an opportunity to verify just three macros: _M_MRX000, _M_ALPHA and _M_PPC. All the rest are defined when different C++ compilers are used to compile my project for different platforms. I also corrected a little inconsistency with _M_IA64 macro: #if defined ( _M_IA64 ) #pragma message ( "*** Message: Compiling for Intel Processing Unit ( 64-bit Itanium ) ***" ) #endif
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
I did a quick verification on how legacy C++ compilers are dealing with it and I did not find anything except for a note: ... /* dos.h Defines structs, unions, macros, and functions for dealing with MSDOS and the Intel iAPX86 microprocessor family. ... As you can see in 1992 a generic term 'iAPX86 microprocessor' was used in Turbo C++ v3.0.
0 Kudos
Judith_W_Intel
Employee
1,443 Views
>My understanding is as follows: if some project is compiled for a 64-bit platform then _M_X64 has to be defined. If Intel C++ compiler defines >the macro on a 64-bit WIndows platform and doesn't define the macro on 64-bit Linux or Mac platforms it doesn't look right because all macros >with a prefix '_M_' are ANSI pre-defined macros It makes no difference what ANSI/ISO says. On Windows platform we predefine the same macros as the Microsoft compiler and on Linux we predefine the same macros as the GNU compiler. This is necessary for compatibility.
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
>>...It makes no difference what ANSI/ISO says... Is that an official statement from Intel? Does it mean that Intel C++ compiler team and support guys don't want to take ANSI standard into account? >>...and on Linux we predefine the same macros as the GNU compiler. This is necessary for compatibility... It means that if the GNU C/C++ compiler has a _M_X64 bug then Intel C++ compiler on Linux platform perfectly reproduces it because of compatibility. It makes no sense at all. I see this again and again that Intel C++ compiler team simply copies some feature(s) or functionality without doing a proper analysis and without asking a question "What if this is wrong in the GNU compiler?".
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
[ A statement from Bernhard ] >>...I had some trouble compiling some opens-ource code with the intel C++ compiler (version 13.0.1 20121010, intel64 architecture)... Could you specify on what platform you're working? That is, a 64-bit WIndows, Linux or Mac?
0 Kudos
Georg_Z_Intel
Employee
1,443 Views
Hello Sergey, maybe I should express this clearer. _M_* macros are Microsoft* specific only - please see this: http://msdn.microsoft.com/en-us/library/vstudio/b0084kay.aspx No one in the GNU* world would ever expect those to be oblige. Hence we don't handle them in our Linux* and Mac OS* X compilers, too. Both worlds are different by design - just think about LP64 vs. LLP64! Back to the original question: Is there a platform independent way to test for 64 bit compilation? Answer: There is not. It always requires to take the platform into account. Even if Intel compilers provide the Microsoft* specific macros for Linux*, it won't work with GNU* compilers, thus being another dead-end regarding portability. Best regards, Georg Zitzlsberger
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
Thank you, Georg! I will need to take into account these differences. I just checked a MinGW documentation and I found two notes: Note 1 ... `__LP64__' `_LP64' These macros are defined, with value 1, if (and only if) the compilation is for a target where `long int' and pointer both use 64-bits and `int' uses 32-bit. ... Note 2 .... System-specific Predefined Macros -------------------------------------------------------- The C preprocessor normally predefines several macros that indicate what type of system and machine is in use. They are obviously different on each target supported by GCC. This manual, being for all systems and machines, cannot tell you what their names are, but you can use `cpp -dM' to see them all. *Note Invocation::. All system-specific predefined macros expand to the constant 1, so you can test them with either `#ifdef' or `#if'. The C standard requires that all system-specific macros be part of the "reserved namespace". All names which begin with two underscores, or an underscore and a capital letter, are reserved for the compiler and library to use as they wish. However, historically system-specific macros have had names with no special prefix; for instance, it is common to find `unix' defined on Unix systems. For all such macros, GCC provides a parallel macro with two underscores added at the beginning and the end. If `unix' is defined, `__unix__' will be defined too. There will never be more than two underscores; the parallel of `_mips' is `__mips__'. When the `-ansi' option, or any `-std' option that requests strict conformance, is given to the compiler, all the system-specific predefined macros outside the reserved namespace are suppressed. The parallel macros, inside the reserved namespace, remain defined. We are slowly phasing out all predefined macros which are outside the reserved namespace. You should never use them in new programs, and we encourage you to correct older code to use the parallel macros whenever you find it. We don't recommend you use the system-specific macros that are in the reserved namespace, either. It is better in the long run to check specifically for features you need, using a tool such as `autoconf'. ...
0 Kudos
TimP
Honored Contributor III
1,443 Views
As Sergey hints, a typical method for distinguishing 32- vs. 64-bit platform is by C pointer size. I think the method based on e.g. sizeof(int *) or (C99) PTRDIFF_MAX is as close as you could call to a standard C method. If your dependencies on 32- vs. 64-bit are covered by such standard facilities, evidently you should take advantage of them. The C standard doesn't deal at all with pre-defined macros which distinguish platform environment. As mentioned earlier in the thread, the Intel compilers usually set the same macros as the Microsoft or gnu compiler which is being modeled, This leaves the __INTEL_COMPILER macros as a way to distinguish from those compilers. There have been some weakly documented macros you could set to turn off Microsoft bug compatibility for certain cases, but I don't see how that is relevant to the original topic of this thread. In the case of known bugs in gnu compilers, it's usually been possible to get bug fixes quickly enough that the best solution was to update compilers to compatible versions.
0 Kudos
SergeyKostrov
Valued Contributor II
1,443 Views
>>...the _M_X64 macro is only defined for the Windows* version of our compiler... I tested two very simple workarounds to resolve that problem if some C/C++ compiler doesn't define _M_X64 macro ( or _M_??? like macros ): [ Solution 1 ] ... // Define for a 64-bit platform ( in some header or in a makefile ) #define _SIZEOF_INT 4 #define _SIZEOF_SIZE_T 8 ... #if ( _SIZEOF_INT == 4 && _SIZEOF_SIZE_T == 8 ) #pragma message ( "Compiling for a 64-bit platform" ) #define _M_X64 #endif ... [ Solution 2 ] Define _M_X64 macro in a makefile project file for a 64-bit Linux platform. [ Note ] >>..._M_* macros are Microsoft* specific only... Even if _M_X64 macro has a letter M it doesn't stand for Microsoft. Even if these macros are Microsoft specific the letter M stands for Machine and it is a more generic term. A letter L ( in _LP64 macro ) stands for Linux and, of course, that is why Microsoft doesn't support / use it. As I already mentioned it is no longer a problem for me since workarounds are simple and working.
0 Kudos
TimP
Honored Contributor III
1,443 Views
As Sergey points out, if your actual concern is the nature of size_t, there also you should simply rely on standard syntax to make your code portable. On most current platforms, of course, size_t and pointer types will match as 32- or 64-bit data types.
0 Kudos
Reply