I'm trying to use Microsoft's <winapifamily.h>
and the WINAPI_FAMILY_PARTITION
macro. I working with a VS2012 ARM Developer Prompt from the Visual Studio tools menu. When I use the macros in the code below:
#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(WINAPI_FAMILY)
# if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# undef SOCKETS_AVAILABLE
# endif
#endif
Then it results in:
cl.exe /nologo /W4 /D_MBCS /Zi /TP /EHsc /MD /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP /c wait.cpp
wait.cpp
c:\...\config.h(548) : fatal error C1012: unmatched parenthesis : missing ')'
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 11.0
\VC\BIN\x86_ARM\cl.exe"' : return code '0x2'
Line 548 is #if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
.
Deleting the the #if
block clears the immediate error of unmatched parenthesis, but results in a slew of socket related errors elsewhere. So I've got to be able to detect the Windows Store and Windows Phone apps and deactivate the code paths.
Where, exactly, is this unmatched parenthesis, and how do I fix it?
Here's the relevant bits from <winapifamily.h>
. Its coming out of the WIndows Phone Kit. I'm fairly certain I am using it as expected.
/*
* Windows APIs can be placed in a partition represented by one of the below bits. The
* WINAPI_FAMILY value determines which partitions are available to the client code.
*/
#define WINAPI_PARTITION_DESKTOP 0x00000001
#define WINAPI_PARTITION_APP 0x00000002
/*
* A family may be defined as the union of multiple families. WINAPI_FAMILY should be set
* to one of these values.
*/
#define WINAPI_FAMILY_APP WINAPI_PARTITION_APP
#define WINAPI_FAMILY_DESKTOP_APP (WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_APP)
/*
* A constant that specifies which code is available to the program's target runtime platform.
* By default we use the 'desktop app' family which places no restrictions on the API surface.
* To restrict the API surface to just the App API surface, define WINAPI_FAMILY to WINAPI_FAMILY_APP.
*/
#ifndef WINAPI_FAMILY
#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
#endif
/* Macro to determine if a partition is enabled */
#define WINAPI_FAMILY_PARTITION(Partition) ((WINAPI_FAMILY & Partition) == Partition)
/* Macro to determine if only one partition is enabled from a set */
#define WINAPI_FAMILY_ONE_PARTITION(PartitionSet, Partition) ((WINAPI_FAMILY & PartitionSet) == Partition)
/*
* Macro examples:
* The following examples are typical macro usage for enabling/restricting access to header code based
* on the target runtime platform. The examples assume a correct setting of the WINAPI_FAMILY macro.
*
* App programs:
* Explicitly set WINAPI_FAMILY to WINAPI_PARTITION_APP (cannot access DESKTOP partition)
* Desktop programs:
* Leave WINAPI_FAMILY set to the default above (currently WINAPI_FAMILY_DESKTOP_APP)
*
* Note: Other families and partitions may be added in the future.
*
*
* The WINAPI_FAMILY_PARTITION macro:
* Code-block is available to programs that have access to specified partition.
*
* Example: Available to App and Desktop programs
* #if WINAPI_FAMILY_PARTITION( WINAPI_PARTITION_APP )
*
* Example: Available to Desktop programs
* #if WINAPI_FAMILY_PARTITION( WINAPI_PARTITION_DESKTOP )
*
*
* The WINAPI_FAMILY_ONE_PARTITION macro:
* Code-block is available to programs that have access to specified parition, but not others in the partition set.
*
* Example: Available only to App programs
* #if WINAPI_FAMILY_ONE_PARTITION( WINAPI_FAMILY, WINAPI_PARTITION_APP )
*
* Example: Available only to Desktop programs
* #if WINAPI_FAMILY_ONE_PARTITION( WINAPI_FAMILY, WINAPI_PARTITION_DESKTOP )
*
* Example: Available to App, but not Desktop programs
* #if WINAPI_FAMILY_ONE_PARTITION( WINAPI_FAMILY_DESKTOP_APP, WINAPI_PARTITION_APP )
*/
<winapifamily.h>
isn't included by default. If you don't include it (preferably via #include
but /FI
is also an option) then the preprocessor will replace (the undefined) WINAPI_FAMILY_PARTITION
and WINAPI_PARTITION_DESKTOP
with 0
. This means
# if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
is equivalent to
# if !(0(0))
This isn't a valid preprocessing expression. Such mistakes can be found by instructing the compiler/preprocessor to emit a diagnostic. MSVC has C4668. It's a level 4 warning but off by default. So you have to enable it with /w44668
. GCC has -Wundef
.