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>)
Related
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
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.
I have a process which processes a lot of files (~96,000 files, ~12 TB data). Several runs of the process has left the files scattered about the drive. Each iteration in the process, uses several files. This leads to a lot of whipsawing around the disk collecting the files.
Ideally, I would like the process to write the files it uses in order, so that the next run will read them in order (file sizes change). Is there a way to hint at a physical ordering/grouping, short of writing to the raw partition?
Any other suggestions would be helpful.
Thanks
There are two system calls you might lookup: fadvise64, fallocate tell the kernel how you intend to read or write a given file.
Another tip is the "Orlov block allocator" (Wikipedia, LWN) affects the way the kernel will allocate new directories and file-entries.
In the end I decided not to worry about writing the files in any particular ordering. Instead, before I started a run, I would figure out where the first block of each file was located, and then sort the file processing order by first block location. Not perfect, but it did make a big difference in processing times.
Here's the C code I used to get the first block of supplied file list I adapted it from example code I found online (can't seem to find the original source).
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/fs.h>
//
// Get the first block for each file passed to stdin,
// write filename & first block for each file to stdout
//
int main(int argc, char **argv) {
int fd;
int block;
char fname[512];
while(fgets(fname, 511, stdin) != NULL) {
fname[strlen(fname) - 1] = '\0';
assert(fd=open(fname, O_RDONLY));
block = 0;
if (ioctl(fd, FIBMAP, &block)) {
printf("FIBMAP ioctl failed - errno: %s\n", strerror(errno));
}
printf("%010d, %s\n", block, fname);
close(fd);
}
return 0;
}
Can ISPP macros call emit and expr?
I have code as follows:
#if oemid == "company1"
;Company 1
#define OEMName "Company 1"
#define OEMDir "..\Customisation\Company1\"
#Include "P:\Common\Setups\Japanese.iss"
#define bannerpath OEMDir+"Setup.bmp"
#elif oemid == "company2"
;Company 2
#define OEMName "Company 2"
#define OEMDir "..\Customisation\Company2\"
#define bannerpath OEMDir+"Setup.bmp"
#define OEMIcon "{app}\OEMIcon.ico"
#elif oemid == "Company 3"
;Company 3
#define OEMDir "..\Customisation\Company3\"
etc...
with each custom setup built with a stub ISS script that sets the id and includes the main ISS script.
I'm trying to convert this to a generic call which is implemented in the stub script:
#expr OEMInit1()
and:
#define OEMInit1() \
emit ";Company 1" \
define OEMDir "..\Customisation\Company1\" \
define bannerpath OEMDir+"Setup.bmp"
This is failing with:
[ISPP] Error at 3:23 in macro OEMInit1:
Undeclared identifier: "emit".
How do I convince ISPP that it's another directive instead of an identifier?
If I have completely the wrong end of the stick, fell free to hit me with it :)
Thanks
Thank to Gavin on the Inno newsgroup who pointed me to #sub
#sub OEMInit1
;company 1"
#define public OEMDir "..\Customisation\Company1\"
#define public bannerpath OEMDir+"Setup.bmp"
#endsub
Note the "public" so it can be access in the calling code.
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