I tried to write a wide version of __FUNCTION__ to support portable code (Windows and Linux)
#include <stdio.h>
#include <wchar.h>
#include <errno.h>
typedef wchar_t WCHAR;
typedef const wchar_t * PCWCH;
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#ifdef _WIN32
#define __WFUNCTION__ WIDEN(__FUNCTION__) L"(): "
#elif __linux__
#define MAX_FUNC_NAME_SIZE 1024
WCHAR func_name[MAX_FUNC_NAME_SIZE];
#define __WFUNCTION__ \
(AsciiStrToUnicodeStr(__FUNCTION__, func_name, MAX_FUNC_NAME_SIZE) == 0) ? func_name : L"(): "
#endif
int AsciiStrToUnicodeStr(const char *src, WCHAR *destination, unsigned int dest_max)
{
size_t retval;
if (!src || !destination || (dest_max == 0)) {
return -EINVAL;
}
retval = mbstowcs(destination, src, dest_max);
return (retval == -1) ? retval : 0;
}
void DbgTrace(PCWCH pwcFormat,...)
{
wprintf(L"%ls\n", pwcFormat);
}
void test()
{
DbgTrace(__WFUNCTION__ L"ERROR: Null string passed\r\n");
}
int main()
{
DbgTrace(__WFUNCTION__ L"ERROR: Null string passed\r\n");
test();
}
The output is only containing the name of the function, but not the concatenated string.
What is the mistake in the above code.
Added output of Preprocessor:
void test()
{
DbgTrace((AsciiStrToUnicodeStr(__FUNCTION__, func_name, 1024) == 0) ? func_name : L"(): " L"ERROR: Null string passed\r\n");
}
__FUNCTION__ (which should be spelled __func__ in C99) is not a string literal; it is effectively an implicitly-defined character array. So you can't create a string literal out of it with literal concatenation. (At least, not in standard C. MSVC might treat __FUNCTION__ as a string literal, but it's not portable.)
String literal concatenation is done by right after preprocessing, and can only be applied to string literals, not variables. func_name " extra text" would be a syntax error.
But that's not what the macro expansion produces, as you can see. The literals being concatenated are L"(): " andL"error: NULL string passed".
Note that if __func__ were a string literal, you could turn it into a wide string literal with string concatenation. Eg:
L"" __FILE__ ": the file"
is a valid wide string literal. (But it won't work on Windows. See https://stackoverflow.com/a/21789691/1566221).
Since __func__ is not a string literal, there is no way to extend it in the preprocessor. (Nor to convert it to a wide string). Your best bet is to use it by itself ina printf call (or wprintf):
printf("%s %s, funcname, message);
Related
I want to implement a variadic function which behaves like printf, except that it prints some prefix. For example, let's say I want the prefix to be the value of time(0). if I call:
wrapped_printf("Hello, world %d", 5678);
I'll expect something like:
1571441246 Hello, world 5678
as the output.
Obviously, replacing the format string is not a big deal; it's the variadic business that's giving me trouble. Should I implement this as a function taking ...? Taking a va_list? And how do I prepend my extra arguments?
This is what I have right now. It compiles and runs (it's valid C89 even...), but the extra arguments get messed up.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
int wrapped_printf(const char* format_str, ...)
{
static const char* const prefix = "%d ";
static const size_t prefix_length = 3;
va_list ap;
size_t format_string_length = strlen(format_str);
char* const prefixed_format_str = malloc(format_string_length + prefix_length + 2);
/* 1 for the trailing '\0' and 1 for a line break */
if (prefixed_format_str == NULL) { exit(EXIT_FAILURE); }
strncpy(prefixed_format_str, prefix, prefix_length);
strncpy(prefixed_format_str + prefix_length, format_str, format_string_length);
prefixed_format_str[prefix_length + format_string_length] = '\n';
prefixed_format_str[prefix_length + format_string_length + 1] = '\0';
va_start(ap, format_str);
return printf(
prefixed_format_str,
(int) time(0),
ap);
va_end(ap);
}
int main()
{
wrapped_printf("Hello world %d\n", 5678);
return EXIT_SUCCESS;
}
See it failing on Coliru.
Notes:
Only one call must be made - but it can be either to printf() or vprintf().
One can use a large string buffer, sprintf() the prefix into it, then sprintf() the original arguments afterwards; but that's also not what I mean.
I don't mind using compiler-specific code - but if you suggest that, please try covering more than a single compiler on more than a single platform - and especially GCC or clang on GNU/Linux with an AMD64 processor.
It is totally not possible to prepend arguments to a va_list portably in plain C. It can be done for sure, but it would require compiler-level wizardry for each architecture and compiler and calling-convention.
For a portable way, a library like libffi and a parser for the format strings...
I suggest that if possible you'd go for a macro instead, if you're lucky enough to be on C99+; then you can prepend "%d " to the format string with compile-time string catenation and add the number in the arguments rather easily. But the format need to be a string literal for this.
Or if you really need to use a function then I don't get the restriction of not using printf separately for the prefix followed by these - the output would be line-buffered or fully-buffered so there would not likely be any difference.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#define wrapped_printf_macro(f_, ...) \
printf("%lld " f_, (long long)time(0), __VA_ARGS__)
int wrapped_printf(const char* format_str, ...)
{
static const char* const prefix = "%d ";
static const size_t prefix_length = 3;
va_list ap;
printf("%lld ", (long long int)time(0));
va_start(ap, format_str);
vprintf(format_str, ap);
va_end(ap);
}
int main()
{
wrapped_printf_macro("Hello world %d\n", 5678);
wrapped_printf("Hello world %d\n", 5678);
return EXIT_SUCCESS;
}
Is there a way to use the _Generic keyword multiple times in the same expression to create a single string literal?
What I am looking for is a way to for example generate a single format string to pass to printf, with all the conversion specifiers adapted to the proper types.
When writing this answer I ended up with a rather ugly work-around:
#include <stdio.h>
typedef struct {
int a;
char b;
long c;
} ABC;
// printf conversion specifiers:
#define CS(x) \
_Generic((x), \
int: "%d", \
char: "%c", \
long: "%ld")
int main (void)
{
ABC abc = {1, 'a', 2};
printf(CS(abc.a), abc.a); printf(" ");
printf(CS(abc.b), abc.b); printf(" ");
printf(CS(abc.c), abc.c); printf(" ");
return 0;
}
6 printf calls instead of 1, hardly ideal.
The problem is that I can't find a way to combine _Generic and string literal concatenation by the pre-processor, like this:
printf(CS(abc.a) " ", abc.a); // doesnt work
printf(CS(abc.a) CS(abc.b), abc.a, abc.b); // doesnt work either
Because apparently generic macros don't count as string literals in the pre-processor, so string literal concatenation isn't possible. I toyed around with "stringification" macros but no luck there.
I'm going to say that the answer is NO.
First, the _Generic keyword is not (and cannot possibly be) a pre-processor directive. A generic-selection is a primary expression, as defined in section 6.5.1. Given the input
printf(CS(abc.a) "hello", abc.a);
the output from the preprocessor (generated by the -E compiler option) is:
printf(_Generic((abc.a), int: "%d", char: "%c", long: "%ld") "hello", abc.a);
Notice that string concatenation is not possible because the generic-selection has not been evaluated. Also note that it's impossible for the pre-processor to evaluate since it requires knowledge that abc is a structure of type ABC, that has member a. The pre-processor does simple text substitution, it has no knowledge of such things.
Second, the compiler phases defined in section 5.1.1.2 don't allow evaluation of _Generic keywords before string concatenation. The relevant phases, quoted from the spec, are
Adjacent string literal tokens are concatenated.
White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. The resulting
tokens are syntactically and semantically analyzed and translated as a
translation unit.
The _Generic keyword must be evaluated in phase 7, since it requires knowledge that is only available after tokens have been syntactically and semantically analyzed, e.g. that abc is a structure with member a. Hence, multiple _Generic keywords cannot take advantage of string concatenation to produce a single string literal.
Nice question, you can paste a string passing another parameter:
#include <stdio.h>
typedef struct {
int a;
char b;
long c;
} ABC;
// printf conversion specifiers:
#define CS2(x, y) \
_Generic((x), \
int: "%d" y, \
char: "%c" y, \
long: "%ld" y)
int main (void)
{
ABC abc = {1, 'a', 2};
printf(CS2(abc.a, "Hello"), abc.a);
return 0;
}
Just for the record, it turns out it is possible to generate a string constant based on _Generic at compile-time, by using other dirty tricks than those available from the pre-processor.
The solution I came up with is so ugly that I barely dare to post it, but I'll do so just to prove it possible.
Don't write code like this!
#include <stdio.h>
typedef struct {
int a;
char b;
long c;
} ABC;
// printf conversion specifiers:
#define CS(x) \
_Generic((x), \
int: "%d", \
char: "%c", \
long: "%ld")
#pragma pack(push, 1)
#define print2(arg1,arg2) \
{ \
typedef struct \
{ \
char arr1 [sizeof(CS(arg1))-1]; \
char space; \
char arr2 [sizeof(CS(arg2))-1]; \
char nl_nul[2]; \
} struct_t; \
\
typedef union \
{ \
struct_t struc; \
char arr [sizeof(struct_t)]; \
} cs2_t; \
\
const cs2_t cs2 = \
{ \
.struc.arr1 = CS(arg1), \
.struc.space = ' ', \
.struc.arr2 = CS(arg2), \
.struc.nl_nul = "\n" \
}; \
\
printf(cs2.arr, arg1, arg2); \
}
#pragma pack(pop)
int main (void)
{
ABC abc = {1, 'a', 2};
print2(abc.a, abc.b);
print2(abc.a, abc.c);
print2(abc.b, abc.c);
return 0;
}
Output:
1 a
1 2
a 2
Explanation:
The macro print2 is a wrapper around printf and prints exactly 2 arguments, no matter type, with their correct conversion specifiers.
It builds up a string based on a struct, to which the conversion specifier string literals are passed. Each array place-holder for such a conversion specifier was purposely declared too small to fit the null termination.
Finally, this struct is dumped into a union which can interpret the whole struct as a single string. Of course this is quite questionable practice (even though it doesn't violate strict aliasing): if there is any padding then the program will fail.
I know you can return a character string from a normal function in C as in this code
#include <stdio.h>
char* returnstring(char *pointer) {
pointer="dog";
return pointer;
}
int main(void)
{
char *dog = NULL;
printf("%s\n", returnstring(dog));
}
However, I can't find a way to be able to return character strings in #define functions, as in this code
#include <stdio.h>
#define returnstring(pointer) { \
pointer="dog"; \
return pointer; \
}
int main(void)
{
char *dog = NULL;
printf("%s\n", returnstring(dog));
}
I know that there are workarounds(like using the first program). I just want to know if it is possible
Thinking about a "#define function" is, IMO, the wrong way to approach this.
#define is a blunt instrument which amounts to a text find/replace. It knows little to nothing about C++ as a language, and the replace is done before any of your real code is even looked at.
What you have written isn't a function in its own right, it is a piece of text that looks like one, and it put in where you have written the alias.
If you want to #define what you just did, that's fine (I didn't check your example specifically, but in general, using #define for a function call and substituting the arguments is possible), but think twice before doing so unless you have an amazing reason. And then think again until you decide not to do it.
You can't "return" from a macro. Your best (ugh... arguably the "best", but anyway) bet is to formulate your macro in such a way that it evaluates to the expression you want to be the result. For example:
#define returnstring(ptr) ((ptr) = "hello world")
const char *p;
printf("%s\n", returnstring(p));
If you have multiple expression statements, you can separate them using the horrible comma operator:
#define even_more_dangerous(ptr) (foo(), bar(), (ptr) = "hello world")
If you are using GCC or a compatible compiler, you can also take advantage of a GNU extension called "statement expressions" so as to embed whole (non-expression) statements into your macro:
#define this_should_be_a_function(ptr) ({ \
if (foo) { \
bar(); \
} else { \
for (int i = 0; i < baz(); i++) { \
quirk(); \
} \
} \
ptr[0]; // last statement must be an expression statement \
})
But if you get to this point, you could really just write a proper function as well.
You don't return anything from a #defined macro. Roughly speaking, the C preprocessor replaces the macro call with the text of the macro body, with arguments textually substituted into their positions. If you want a macro to assign a pointer to "dog" and evaluate to the pointer, you can do this:
#define dogpointer(p) ((p)="dog")
The thing is returnstring as a macro does not do what it says; it also assigns the value to the parameter. The function does as it says, even if it (somewhat oddly) uses its parameter as a temporary variable.
The function is equivalent to:
char* returnstring(char *ignored) {
return "dog";
}
The function macro is much the same as:
#define returnstring(pointer) pointer = "dog"
Which begs the question, why not call it assign_string?
Or why not just have:
#define dogString "dog"
And write:
int main(void)
{
char *dog = NULL;
printf("%s\n", dog = dogString);
}
The function for assignString is:
char* assignstring(char **target{
*target= "dog";
return *target;
}
You can then have a macro:
assign_string_macro(pointer) assignstring(&pointer)
Ultimately if you want to "return character strings in #define functions", then all you need is:
#define returnstring(ignored) "dog"
Is is possible to convert any variable of any type to string?
I wrote the following
#define TO_STRING(val) #val
Is this a valid way of converting a variable into a string?
I think the code below will do your work. I uses the standard sprintf function, which prints data from any type to a string, instead to stdout. Code:
#include <stdio.h>
#define INT_FORMAT "%d"
#define FLOAT_FORMAT "%f"
#define DOUBLE_FORMAT "%lf"
#define LL_FORMAT "%lld"
// ect ...
#define CONVERT_TO_STRING(FORMAT, VARIABLE, LOCATION) \
do { \
sprintf(LOCATION, FORMAT, VARIABLE); \
} while(false)
int main() {
char from_int[30];
char from_float[30];
char from_double[30];
char from_ll[30];
CONVERT_TO_STRING(INT_FORMAT, 34, from_int);
CONVERT_TO_STRING(FLOAT_FORMAT, 34.234, from_float);
CONVERT_TO_STRING(DOUBLE_FORMAT, 3.14159265, from_double);
CONVERT_TO_STRING(LL_FORMAT, 9093042143018LL, from_ll);
puts(from_int);
puts(from_float);
puts(from_double);
puts(from_ll);
return 0;
}
You will get a string version of the variable's name, i.e. it will convert a to "a". The #when used like this is called the stringification operator.
For example:
#define TO_STRING(val) #val
int main(void)
{
const int a = 12;
print("a is %s\n", TO_STRING(a));
return 0;
}
This will print a is a.
What do you expect to happen?
You can't get the variable's value, of course, since that's not available when the pre-processor runs (which is at compile-time).
try this will work with integers: edit the format string for other data types.
sprintf(str,"%d",value);
I want to concat a string literal and char literal. Being syntactically incorrect, "abc" 'd' "efg" renders a compiler error:
x.c:4:24: error: expected ',' or ';' before 'd'
By now I have to use snprift (needlessly), despite the value of string literal and the char literal being know at compile time.
I tried
#define CONCAT(S,C) ({ \
static const char *_r = { (S), (C) }; \
_r; \
})
but it does not work because the null terminator of S is not stripped. (Besides of giving compiler warnings.)
Is there a way to write a macro to use
"abc" MACRO('d') "efg" or
MACRO1(MACRO2("abc", 'd'), "efg") or
MACRO("abc", 'd', "efg") ?
In case someone asks why I want that: The char literal comes from a library and I need to print the string out as a status message.
If you can live with the single quotes being included with it, you could use stringification:
#define SOME_DEF 'x'
#define STR1(z) #z
#define STR(z) STR1(z)
#define JOIN(a,b,c) a STR(b) c
int main(void)
{
const char *msg = JOIN("Something to do with ", SOME_DEF, "...");
puts(msg);
return 0;
}
Depending on the context that may or may not be appropriate, but as far as convincing it to actually be a string literal buitl this way, it's the only way that comes to mind without formatting at runtime.
Try this. It uses the C macro trick of double macros so the macro argument has the chance to expand before it is stringified.
#include <stdio.h>
#define C d
#define S "This is a string that contains the character "
#define STR(s) #s
#define XSTR(s) STR(s)
const char* str = S XSTR(C);
int main()
{
puts(str);
return 0;
}
I came up with a GCC-specific solution that I don't like too much, as one cannot use CONCAT nestedly.
#include <stdio.h>
#define CONCAT(S1,C,S2) ({ \
static const struct __attribute__((packed)) { \
char s1[sizeof(S1) - 1]; \
char c; \
char s2[sizeof(S2)]; \
} _r = { (S1), (C), (S2) }; \
(const char *) &_r; \
})
int main(void) {
puts(CONCAT ("abc", 'd', "efg"));
return 0;
}
http://ideone.com/lzEAn
C will only let you concatenate string literals. Actually, there's nothing wrong with snprintf(). You could also use strcpy():
strcpy(dest, str1);
dest[strlen(dest)] = c;
strcpy(dest + strlen(dest) + 1, str2);
You could also use a giant switch statement to overcome this limitation:
switch(c) {
case 'a':
puts("part1" "a" "part2");
break;
case 'b':
puts("part1" "b" "part2");
break;
/* ... */
case 'z':
puts("part1" "z" "part2");
break;
}
...but I refuse to claim any authorship.
To put it short, just stick with snprintf().