Prevent space after pre-processor macro replacement - c++11

I am curious if it is possible to eliminate the space that pre-processor inserts/retains (?) after replacing macro token
//Code
#define s std::
void PrintMatches2(std::string str, s regex reg)
//Output
void PrintMatches2(std::string str, std:: regex reg)
/*---------------------------------------^----------Want to eliminate space here*/
TIA
EDIT: Don't understand the reason for down-vote. Question is clear, well formatted.

As #javaLover suggested in his code, it was possible to collapse the macro token and subsequent code using a macro function. (It gets detected)
//Code
#define s() std::
void PrintMatches2(std::string str, s()regex reg)
//Output
void PrintMatches2(std::string str, std::regex reg)

Related

How to use __VA_ARGS__ variadic in 8051

I'm trying to build a project 8051 in Keil IDE.
I have a definition to print information for purposes debug program as following:
#define LOGI(fmt, ...) printf("[I] %s:%u: "fmt, __FILE__, __LINE__, ##__VA_ARGS__)
But there are errors:
log.h(18): error C301: identifier expected
log.h(18): error C301: identifier expected
log.h(18): error C304: bad macro parameter list
Please help me fix this code, thank you.
According to the documentation, Keil C51 is based on C90. So it does not support __VA_ARGS__ that is a C99 addition.
However, you can work around this for example by this trick. Use a parenthesized argument.
#define LOGI(args) \
do { \
printf("[I] %s:%u: ", __FILE__, __LINE__); \
printf args; \
} while (0)
void f(void) {
LOGI(("address of f() = %p\n", f));
}
Another possible solution is to provide an own function with a variable number of arguments, see the example in the documentation. This is a cleaner way because you can use this function without a "hick-up" when reading the source code because of the double parentheses. But be aware that these arguments are not placed in registers, and more memory on stack and in code is used.
#include <stdio.h>
#include <stdarg.h>
void logi(const char* filename, int line, char *fmt, ...) {
va_list arg_ptr;
va_start(arg_ptr, fmt);
printf("[I] %s:%u: ", filename, line);
vprintf(fmt, arg_ptr);
va_end(arg_ptr);
}
void f(void) {
logi(__FILE__, __LINE__, "Hello %u %u", 1 , 2);
}
Note: You might want to switch to another compiler, which supports some newer standard than a 30 years old one.

How to constraint the parameter package type in c++11? And How to implement the template in cpp?

For the first quesion:
I want to write a function to concatenation the strings, and it can receive multiple strings;
#include <string>
#include <vector>
#include <type_traits>
template <class... Args, typename std::enable_if<std::is_same<typename std::decay<Args...>::type, std::string>::type>::type>
std::string foo(const std::string &first, const Args &... senconds) {
std::string delimiter = "$$";
std::string ret = first;
std::vector<std::string> vec{senconds...};
for (auto second = vec.rbegin(); second != vec.rend(); second++) {
ret = delimiter + *second + delimiter + ret;
}
return ret;
}
but when I invoke it like:
std::string name = "x";
name = foo(name, "xxx");
the compiler will throw an error:
error: no matching function for call to ‘foo(std::__cxx11::string&, const char [4])’
and there will be some note:
note: couldn't deduce template parameter ‘<anonymous>’
I think I should modify the constraint in the template, and I've tried all the related methods in the type_traits, but none of them works.
For the second question:
I want to hide the implementation of some function, but for the template function, it's unable to put the definition in the .hpp, and put the implementation in the .cpp, the compiler will throw a undefined reference error. Is there any elegant way to solve this?
Thanks.
There's a bit to unwrap here.
std::decay<Args...>::type can't work. std::decay takes only a single template argument, but you attempt to expand the pack here. The expansion needs to happen on the is_same.
You are also missing a way to aggregate all the is_same predicates. Do you want to and them all or or them all? Presumably and. In C++17 that's easily done with a fold expression, but for C++11 we have to work a bit.
Finally the thing the compiler complains about: std::enable_if<bla>::type evaluates to void if bla is true. That means you're formally expecting a non-type template argument, and the compiler complains because it can't deduce which value of type void it should deduce. This is normally alleviated by forming a pointer to it instead and defaulting it to nullptr: std::enable_if<bla>::type* = nullptr.
It appears (?) that you expect foo(someString, "stringLiteral"); to work. It won't, because a string literal is not a std::string. Maybe you wanted a different predicate, but for this answer I'll stick with the original condition.
Putting all that together:
In C++17, you would write
template <class... Args,
std::enable_if_t<
(std::is_same_v<std::decay_t<Args>, std::string> && ...)
>* = nullptr
>
https://godbolt.org/z/84Dcmt
In C++11, we use this helper and add back the typename and ::type verbosity:
template <class... Args,
typename std::enable_if<
var_and<
std::is_same<typename std::decay<Args>::type, std::string>::value...
>::value
>::type* = nullptr
>
https://godbolt.org/z/2eFyX7
Base on MaxLanghof's answer, I changed the template to:
template <class... Args,
typename std::enable_if<var_and<std::is_constructible<
std::string, Args>::value...>::value>::type * = nullptr>
In this form, the function foo can be invoked like the name = foo(name, stringRed, "xxx").
Thanks #MaxLanghof again.

Is there a way to use _T/TEXT "conditionally" inside a macro?

This question is specific to Visual C++ (you may assume Visual C++ 2005 and later).
I would like to create glue code for a program from unixoid systems (FreeBSD in particular) in order build and run on Win32 with a minimum of changes to the original .c file. Now, most of this is straightforward, but now I ran into an issue. I am using the tchar.h header and TCHAR/_TCHAR and need to create glue code for the err and errx calls (see err(3)) in the original code. Bear with me, even if you don't agree that code using tchar.h should still be written.
The calls to err and errx take roughly two forms, and this is where the problem occurs:
err(1, "some string with %d format specifiers and %s such", ...)
/* or */
err(1, NULL, ...)
The latter would output the error stored in errno (using strerror).
Now, the question is, is there any way to write a generic macro that can take both NULL and a string literal? I do not have to (and will not) care about variables getting passed as the second parameter, only NULL and literal strings.
Of course my naive initial approach didn't account for fmt passed as NULL (using variadic macros!):
#define err(eval, fmt, ...) my_err(eval, _T(fmt), __VA_ARGS__)
Right now I don't have any ideas how to achieve this with macros, because it would require a kind of mix of compile-time and runtime conditionals that I cannot imagine at the moment. So I am looking for an authoritative answer whether this is conceivable at all or not.
The method I am resorting to right now - lacking a better approach - is to write a wrapper function that accepts, just like err and errx, a (const) char * and then converting that to wchar_t * if compiled with _UNICODE defined. This should work, assuming that the caller passes a _TCHAR* string for the variable arguments after the fmt (which is a sane assumption in my context). Otherwise I'd also have to convert %s to %hs inside the format string, to handle "ANSI" strings, as MS calls them.
Here's one solution:
#define _WIN32_WINNT 0x0502
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#ifdef _UNICODE
#define LNULL NULL
#define fn(x) myfn(L ## x)
#else
#define fn(x) myfn(x)
#endif
void myfn(TCHAR * str)
{
if (str == NULL) _tprintf(_T("<NULL>")); else _tprintf(str);
_tprintf(_T("\n"));
}
int main(int argc, char ** argv)
{
fn("hello");
fn(NULL);
return 0;
}

Setting up Visual Studio Intellisense for CUDA kernel calls

I've just started CUDA programming and it's going quite nicely, my GPUs are recognized and everything. I've partially set up Intellisense in Visual Studio using this extremely helpful guide here:
http://www.ademiller.com/blogs/tech/2010/10/visual-studio-2010-adding-intellisense-support-for-cuda-c/
and here:
http://www.ademiller.com/blogs/tech/2011/05/visual-studio-2010-and-cuda-easier-with-rc2/
However, Intellisense still doesn't pick up on kernel calls like this:
// KernelCall.cu
#include <iostream>
#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
__global__ void kernel(void){}
int main()
{
kernel<<<1,1>>>();
system("pause");
return 0;
}
The line kernel<<<1,1>>>() is underlined in red, specifically the one arrow to the left of the first one with the error reading "Error: expected and expression". However, if I hover over the function, its return type and parameters are displayed properly. It still compiles just fine, I'm just wondering how to get rid of this little annoyance.
Wow, lots of dust on this thread. I came up with a macro fix (well, more like workaround...) for this that I thought I would share:
// nvcc does not seem to like variadic macros, so we have to define
// one for each kernel parameter list:
#ifdef __CUDACC__
#define KERNEL_ARGS2(grid, block) <<< grid, block >>>
#define KERNEL_ARGS3(grid, block, sh_mem) <<< grid, block, sh_mem >>>
#define KERNEL_ARGS4(grid, block, sh_mem, stream) <<< grid, block, sh_mem, stream >>>
#else
#define KERNEL_ARGS2(grid, block)
#define KERNEL_ARGS3(grid, block, sh_mem)
#define KERNEL_ARGS4(grid, block, sh_mem, stream)
#endif
// Now launch your kernel using the appropriate macro:
kernel KERNEL_ARGS2(dim3(nBlockCount), dim3(nThreadCount)) (param1);
I prefer this method because for some reason I always lose the '<<<' in my code, but the macro gets some help via syntax coloring :).
Visual Studio provides IntelliSense for C++, the trick from the rocket scientist's blog is basically relying on the similarity CUDA-C has to C++, nothing more.
In the C++ language, the proper parsing of angle brackets is troublesome. You've got < as less than and for templates, and << as shift, remember not long ago when we had to put a space in between nested template declarations.
So it turns out that the guy at NVIDIA who came up with this syntax was not a language expert, and happened to choose the worst possible delimiter, then tripled it, well, you're going to have trouble. It's amazing that Intellisense works at all when it sees this.
The only way I know to get full IntelliSense in CUDA is to switch from the Runtime API to the Driver API. The C++ is just C++, and the CUDA is still (sort of) C++, there is no <<<>>> badness for the language parsing to have to work around.
From VS 2015 and CUDA 7 onwards you can add these two includes before any others, provided your files have the .cu extension:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
No need for MACROS or anything. Afterwards everything will work perfectly.
I LOVED Randy's solution. I'll match and raise using C preprocessor variadic macros:
#ifdef __INTELLISENSE__
#define CUDA_KERNEL(...)
#else
#define CUDA_KERNEL(...) <<< __VA_ARGS__ >>>
#endif
Usage examples:
my_kernel1 CUDA_KERNEL(NUM_BLOCKS, BLOCK_WIDTH)();
my_kernel2 CUDA_KERNEL(NUM_BLOCKS, BLOCK_WIDTH, SHMEM, STREAM)(param1, param2);
I've been learning CUDA and have encountered that exact issue. As others have said, it's just Intellisense problem and can be ignored, but I've found a clean solution which actually removes it.
It seems that <<< >>> is interpreted as a correct code if it's inside a template function.
I've discovered it accidentally when I wanted to create wrappers for kernels to be able to call them from a regular cpp code. It's both a nice abstraction and removes the syntax error.
kernel header file (eg. kernel.cuh)
const size_t THREADS_IN_BLOCK = 1024;
typedef double numeric_t;
// sample kernel function headers
__global__ void sumKernel(numeric_t* out, numeric_t* f, numeric_t* blockSum, size_t N);
__global__ void expKernel(numeric_t* out, numeric_t* in, size_t N);
// ..
// strong-typed wrapper for a kernel with 4 arguments
template <typename T1, typename T2, typename T3, typename T4>
void runKernel(void (*fun)(T1, T2, T3, T4), int Blocks, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
fun <<<Blocks, THREADS_IN_BLOCK >>> (arg1, arg2, arg3, arg4);
}
// strong-typed wrapper for a kernel with 3 arguments
template <typename T1, typename T2, typename T3>
void runKernel(void (*fun)(T1, T2, T3), int Blocks, T1 arg1, T2 arg2, T3 arg3) {
fun <<<Blocks, THREADS_IN_BLOCK >>> (arg1, arg2, arg3);
}
// ...
// the one-argument fun cannot have implementation here
void runKernel(void (*fun)(), int Blocks);
in a .cu file (you will get a syntax error here, but do u ever need a parameter-less kernel function? if not, this and a respective header can be deleted):
void runKernel(void (*fun)(), int Blocks) {
fun <<<Blocks, THREADS_IN_BLOCK >>> ();
}
usage in a .cpp file:
runKernel(kernelFunctionName, arg1, arg2, arg3);
// for example runKernel(expKernel, B, output, input, size);

How do you convert a 'System::String ^' to 'TCHAR'?

i asked a question here involving C++ and C# communicating. The problem got solved but led to a new problem.
this returns a String (C#)
return Marshal.PtrToStringAnsi(decryptsn(InpData));
this expects a TCHAR* (C++)
lpAlpha2[0] = Company::Pins::Bank::Decryption::Decrypt::Decryption("123456");
i've googled how to solve this problem, but i am not sure why the String has a carrot(^) on it. Would it be best to change the return from String to something else that C++ would accept? or would i need to do a convert before assigning the value?
String has a ^ because that's the marker for a managed reference. Basically, it's used the same way as * in unmanaged land, except it can only point to an object type, not to other pointer types, or to void.
TCHAR is #defined (or perhaps typedefed, I can't remember) to either char or wchar_t, based on the _UNICODE preprocessor definition. Therefore, I would use that and write the code twice.
Either inline:
TCHAR* str;
String^ managedString
#ifdef _UNICODE
str = (TCHAR*) Marshal::StringToHGlobalUni(managedString).ToPointer();
#else
str = (TCHAR*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
#endif
// use str.
Marshal::FreeHGlobal(IntPtr(str));
or as a pair of conversion methods, both of which assume that the output buffer has already been allocated and is large enough. Method overloading should make it pick the correct one, based on what TCHAR is defined as.
void ConvertManagedString(String^ managedString, char* outString)
{
char* str;
str = (char*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
strcpy(outString, str);
Marshal::FreeHGlobal(IntPtr(str));
}
void ConvertManagedString(String^ managedString, wchar_t* outString)
{
wchar_t* str;
str = (wchar_t*) Marshal::StringToHGlobalUni(managedString).ToPointer();
wcscpy(outString, str);
Marshal::FreeHGlobal(IntPtr(str));
}
The syntax String^ is C++/CLI talk for "(garbage collected) reference to a System.String".
You have a couple of options for the conversion of a String into a C string, which is another way to express the TCHAR*. My preferred way in C++ would be to store the converted string into a C++ string type, either std::wstring or std::string, depending on you building the project as a Unicode or MBCS project.
In either case you can use something like this:
std::wstring tmp = msclr::interop::marshal_as<std::wstring>( /* Your .NET String */ );
or
std::string tmp = msclr::interop::marshal_as<std::string>(...);
Once you've converted the string into the correct wide or narrow string format, you can then access its C string representation using the c_str() function, like so:
callCFunction(tmp.c_str());
Assuming that callCFunction expects you to pass it a C-style char* or wchar_t* (which TCHAR* will "degrade" to depending on your compilation settings.
That is a really rambling way to ask the question, but if you mean how to convert a String ^ to a char *, then you use the same marshaller you used before, only backwards:
char* unmanagedstring = (char *) Marshal::StringToHGlobalAnsi(managedstring).ToPointer();
Edit: don't forget to release the memory allocated when you're done using Marshal::FreeHGlobal.

Resources