_Pragma preprocessor operator in Visual C++ - visual-c++

Is there something like the ANSI C operator _Pragma in Visual C++?
For example, I'm trying to define the following macro:
#ifdef _OPENMP
#define PRAGMA_IF_OPENMP(x) _Pragma (#x)
#else // #ifdef _OPENMP
#define PRAGMA_IF_OPENMP(x)
#endif // #ifdef _OPENMP
So I can circumvent compiler warnings for unknown #pragma omp ... in older GCC compilers.
Is there a similar means available in VisualC++?

Yes, but it's two underscores: __pragma
I'm not sure about how the omp pragma works, however, here's an example using VC++'s optimize pragma:
#define PRAGMA_OPTIMIZE_OFF __pragma(optimize("", off))
// These two lines are equivalent
#pragma optimize("", off)
PRAGMA_OPTIMIZE_OFF
EDIT: I've just confirmed that the omp pragmas can also be used like this:
#define OMP_PARALLEL_FOR __pragma(omp parallel for)
So, yes, your macro should work if defined as follows (note that your original code incorrectly used the stringizing operator #x:
#ifdef _OPENMP
#define PRAGMA_IF_OPENMP(x) __pragma (x)
#else // #ifdef _OPENMP
#define PRAGMA_IF_OPENMP(x)
#endif // #ifdef _OPENMP

Related

Adding two strings together in the preprocessor

I am currently writing a header to make handling my external libs easier.
Here is the minimal code:
#pragma once
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#define EXTERNAL_PATH STR(C:/C++ Libraries/)
#define LUA_PATH EXTERNAL_PATH STR(lua 5.3.4/)
#define LUA_INCLUDE LUA_PATH STR(include/)
So basically, I include this header and write something like
#include LUA_INCLUDE (add this two strings) "lua.hpp"
How can I link two strings in the preprocessor together ?
Are you looking for ##? And don't stringify (quote) macro params too early because then there is no way back.
Example:
#define MY_QUOTE(a) #a
#define CONCAT_QUOTE(a,b) MY_QUOTE(a##b)
#define CONCAT(a,b) a##b
// this works OK
#include CONCAT(<iostrea, m>)
// this doesn't as iostream should be just in <> rather than "<>"
#include CONCAT_QUOTE(<iostrea, m>)

autoconf check for missing prototype

Is there a better way to write an autoconf test for a missing prototype than by setting CFLAGS to "-Werror -Wimplicit-function-declaration" ?
Specifically, I'm trying to determine if I need to provide my own pwrite(2)
and pread(2). If the environment is strict, pread/pwrite are not defined.
here's what I have now, which works:
AC_INIT([pwrite],[0.0.0],[none],[nothing],[nowhere])
AC_CONFIG_HEADERS([config.h])
old_CFLAGS=$CFLAGS
CFLAGS="-Werror $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
int main(int argc, char **argv) {
int ret = pwrite(99, "blah", 1, 0);
return 0;
} ]) ],
AC_MSG_RESULT([using system pwrite prototype])
AC_DEFINE(HAVE_PWRITE, 1, [pwrite protoype exists]),
AC_MSG_RESULT([no pwrite protoype. using our own])
)
CFLAGS=$old_CFLAGS
AC_OUTPUT()
When I do this, configure CFLAGS=-std=c99 will indeed detect that pwrite is declared implicitly, and configure alone will find a pwrite prototype in unistd.h. However, mucking with CFLAGS inside configure doesn't seem like the "autoconf-y" way to do this.
If you look at the source of the autoconf macros you find that a lot of them save and restore CFLAGS. You need to be very careful using -Werror though, as you might get incorrect results. e.g., if argc, argv are unused - as is ret - a warning (see: -Wunused* flags) will be interpreted as pwrite being unavailable.
Assuming <unistd.h> compiles without warning-as-errors, which it should:
<save CFLAGS>
CFLAGS="$CFLAGS -Werror=implicit-function-declaration"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif]],
[[(void) pwrite(99, "blah", 1, 0);]])],
<action-on-success>,
<action-on-fail>)
<restore CFLAGS>
The (void) cast is probably unnecessary - it's for crazy-strict warnings that will probably not be silent even for system headers, but doesn't hurt. It might be worth looking at the _XOPEN_SOURCE macro value - e.g., setting _XOPEN_SOURCE in this test and the library code.
Saving/restoring CFLAGS is acceptable but for this particular purpose, AC_CHECK_DECLS turns out to be precisely what I was looking for, and furthermore does not have any problems with super-picky compilers or trying to figure out what is the Portland Group compiler equivalent to -Werror-implicit-function-declaration.
AC_INIT([pwrite],[0.0.0],[none],[nothing],[nowhere])
AC_CONFIG_HEADERS([config.h])
AC_CHECK_HEADERS([unistd.h])
AC_CHECK_DECLS([pwrite])
AC_OUTPUT()
and then in my code I do have to check the result a little differently:
#if (HAVE_DECL_PWRITE == 0)
... implement our own pwrite
#endif

What is difference between __va() and phys_to_virt()?

What is difference between __va() and phys_to_virt() ,what is need of these two separate implementation for same purpose, any difference between these two?
phys_to_virt and __va are preprocessor macros. phys_to_virt:
#if !defined(CONFIG_MMU)
#define virt_to_phys(address) ((unsigned long)(address))
#define phys_to_virt(address) ((void *)(address))
#else
#define virt_to_phys(address) (__pa(address))
#define phys_to_virt(address) (__va(address))
#endif
And __va
#define __va(x) ((void *)((unsigned long) (x)))
If CONFIG_MMU is not defined then are equals.

Why NTDDI_VERSION macro changes its value from cpp it includes to ntdddisk.h?

Why NTDDI_VERSION macro changes its value from cpp it includes to ntdddisk.h ?
I am using Visual Studio 2012 with cumulative update 4, and building on Windows 7 x64.
In one CPP i need to call new IOCTL_ .. for WIN 8.
In the CPP there is #include
ntdddisk.h defines the new IOCTL_ for WIN 8 under the guarded condition:
#if (NTDDI_VERSION >= NTDDI_WIN8)
...
#endif
Inside that cpp the NTDDI_VERSION macro has value NTDDI_WIN8 (as expected result from include sdkddkver.h and compilation with /D_WIN32_WINNT=0x0602)
However, in ntdddisk.h the value for NTDDI_VERSION macro has value < NTDDI_VISTA, that is, less than NTDDI_WIN8
Compilation fails with error
error C2065: 'IOCTL_..' : undeclared identifier
Looks like a bug unless i miss something else. Thoughts?
Details are:
In the CPP file there are these includes
#pragma once
// Needed for new IOCTL_ for WIN 8
#include <sdkddkver.h>
#include <windows.h>
// Check NTDDI_VERSION ...
#if (NTDDI_VERSION >= NTDDI_WIN8)
// Value is NTDDI_WIN8 as expected
// #include <TROUBLE.h>
#endif
#pragma pack(8)
#include <ntdddisk.h>
#include <ntddscsi.h>
#include <lm.h>
#include <objbase.h>
/*=== IMPORTANT: this struct needs to have 8-byte packing ===*/
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {
SCSI_PASS_THROUGH spt;
ULONG Filler; // realign buffers to double word boundary
UCHAR SenseBuf[32];
UCHAR DataBuf[512];
} SCSI_PASS_THROUGH_WITH_BUFFERS;
#pragma pack()
Compilation with CL has these parameters including with -D_WIN32_WINNT=0x0602
cl -nologo #COMPL.TMP /Fo..\\..\\..\\optimized\\obj\\x86\\CPP.obj CPP.cpp
COMPL.TMP contains
/I*** application-headers ***
-D_AFXDLL -c -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DBTREEDB -O2 -Ox -MD -Zi -DNT_CLIENT -DWIN32 -D"_CONSOLE" -D_THREADS -D_OPSYS_TYPE=DS_WINNT -DPSAPI_VERSION=1 -D_WIN32_WINNT=0x0602 -TP -DMBCS=1 -D_LONG_LONG=1 -D_DSM_VLK_BTREE -DDSM_WIDECHAR -D_UNICODE -DUNICODE -DUSE_XML=1 -DXMLUTIL_EXPORTS=1 -DUSE_XERCES_2_8=1 -DPEGASUS_PLATFORM_WIN32_IX86_MSVC=1 -DPEGASUS_USE_EXPERIMENTAL_INTERFACES -Zp1 -D_DSM_LONG_NAME -W3 -EHsc -GF
The problem isn't with the _WIN32_WINNT or NTDDI_VERSION macros.
The problem is that windows.h indirectly includes winioctl.h which has the following curious couple of lines about halfway through:
#ifndef _NTDDDISK_H_
#define _NTDDDISK_H_
Unsurprisingly, ntdddisk.h starts with those very same lines and therefore is effectively not included at all.
I couldn't easily come up with a combination or ordering of headers that would work around this problem - I think it's something that MS really needs to fix.
However, the following terrible workaround (that I really don't suggest, unless you can't get any help from MS) seemed to get the compiler to actually process ntdddisk.h:
#define _NTDDDISK_H_
#include <windows.h>
#undef _NTDDDISK_H_
But, I suspect there may be other problems that might pop up as a result of this hack - so if you decide to use it, please test carefully.
I am not sure that this is what i need, but the compilation worked after inserting
#define _NTDDDISK_H_
#include <windows.h>
...
#undef _NTDDDISK_H_
#include <ntdddisk.h>
Thanks for suggestion.

Latest ATL version

I couldn't find the exact number of current Active Template Library (ATL) which distribute along with Visual Studio 2012. Does anyone have an idea about the exact version number ?
From atldef.h:
/////////////////////////////////////////////////////////////////////////////
// Master version numbers
#define _ATL 1 // Active Template Library
#define _ATL_VER 0x0A00 // Active Template Library version 10.00
#ifndef _ATL_FILENAME_VER
#define _ATL_FILENAME_VER "100"
#endif
#ifndef _ATL_FILENAME_VER_NUM
#define _ATL_FILENAME_VER_NUM 100
#endif
#ifndef _ATL_VER_RBLD
#define _ATL_VER_RBLD "10.00"
#endif

Resources