I have implemented my custom sizeof operator as below
#define my_sizeof(x) do{\
typeof(x) _a;\
(char*)(&_a + 1) - (char*)(&_a);\
}while(0)
If I compile it I get the error
test.c:26:22: error: expected expression before ‘do’
Can't figure out what I am doing wrong.
My main function is given below.
int main()
{
int a;
unsigned long long b;
double c;
printf("size of a %zd \n",my_sizeof(a));
printf("size of b %zd \n",my_sizeof(b));
printf("size of c %zd \n",my_sizeof(c));
return 0;
}
Your macro expands to a do loop. A do loop is not an expression, and does not produce a value. The compiler is telling you that you cannot use a do loop where you are trying to use one, and it is right.
There is no clean alternative in C, since you cannot declare a variable inside an expression.
This is because of the way you macro is preprocessed. The preprocessor output (which you may get using gcc -E file.c) will look like this (stripped for a variable only):
int main() {
int a;
printf("size of a %zd \n", do { typeof(a) _a; (char*)(&_a + 1) - (char*)(&_a); } while (0));
return 0;
}
which is not a correct C syntax. You could use do..while macro like that though (without an assignment or nesting it inside another function):
MY_MACRO(x);
Refer to this article for some more information.
A do/while loop can't return a value. You could instead use a GCC-style statement expression to do what you're trying:
#define my_sizeof(x) ({ \
typeof(x) _a; \
(char*)(&_a + 1) - (char*)(&_a); \
})
Clang & GCC support statement expressions for sure, I don't know about any other compilers off the top of my head.
Related
I know the following is a very trivial example, but how would I convert the following into a single function call that uses the preprocessor ## 'glue' operator?
void print_string(char *s)
{
printf("%s\n", s);
}
void print_num(int n)
{
printf("%d\n", n);
}
int main(void)
{
print_string("Hello");
print_num(5);
}
The only thing I can thing of (which doesn't really simplify anything) is:
#define PRINT(type) print_ ## type
PRINT(string)("Hello");
PRINT(num)(4);
Or, is there a better way to use that?
You can make the identification to be the first function argument:
#define PRINT(type, value) print_ ## type(value)
PRINT(string, "Hello");
PRINT(num, 4);
But I see no value in that over just writing printf, as someone will have to learn to write num in case of int, he might as well learn to use %d anyway:
printf("%s\n", "Hello");
printf("%d\n", 4);
Type dispatch is not possible in pre-processor - it's not aware of types. In C11 there's _Generic that allows compiler to choose different function depending on type:
#define PRINT(value) _Generic((value), \
char *: print_string, \
int: print_int)(value)
PRINT("Hello");
PRINT(4);
By overloading the macro on each argument and applying such _Generic macro on each argument it's possible to build a replacement for C++ std::cout. So a little self-promotion: that's a topic I explored in yio library that allows just to do:
yprint("Hello ", 4, "\n");
uint32_t fail_count = 0;
...
if(is_failed)
if(fail_count < UINT32_MAX - 1 )
++fail_count;
It works fine, but this code is fragile. Tomorrow, I may change the type of fail_count from uint32_t to int32_t and I forget to update UINT32_MAX.
Is there any way to assert fail_count is a uint32_t at the function where I have written my ifs?
P.S. 1- I know it is easy in C++ but I'm looking for a C way.
P.S. 2- I prefer to use two asserts than relying on the compiler warnings. Checking the number size via sizeof should work but is there any way to distinguish if type is unsigned?
As of C11, you can use a generic selection macro to produce a result based on the type of an expression. You can use the result in a static assertion:
#define IS_UINT32(N) _Generic((N), \
uint32_t: 1, \
default: 0 \
)
int main(void) {
uint32_t fail_count = 0;
_Static_assert(IS_UINT32(fail_count), "wrong type for fail_count");
}
You could of course use the result in a regular assert(), but _Static_assert will fail at compile time.
A better approach could be dispatching the comparison based on type, again using generic selection:
#include <limits.h>
#include <stdint.h>
#define UNDER_LIMIT(N) ((N) < _Generic((N), \
int32_t: INT32_MAX, \
uint32_t: UINT32_MAX \
) -1)
int main(void) {
int32_t fail_count = 0;
if (UNDER_LIMIT(fail_count)) {
++fail_count;
}
}
As you mentioned GCC, you can use a compiler extension to accomplish this in case you are not using C11:
First write a macro that emulates the C++ is_same. And then call it with the types you want to compare.
A minimal example for your particular case:
#include<assert.h>
#define is_same(a, b) \
static_assert(__builtin_types_compatible_p(typeof(a), typeof(b)), #a " is not unsigned int")
int main()
{
int fail_count = 0;
is_same(fail_count, unsigned int);
}
The compiler asserts:
<source>: In function 'main':
<source>:4:3: error: static assertion failed: "fail_count is not unsigned int"
static_assert(__builtin_types_compatible_p(typeof(a), typeof(b)), #a " is not unsigned int")
^~~~~~~~~~~~~
<source>:9:5: note: in expansion of macro 'is_same'
is_same(fail_count, unsigned int);
^~~~~~~
See Demo
What about a low-tech solution that works even with K&R C and any compiler past and present?
Place the right comment in the right place:
/*
* If this type is changed, don't forget to change the macro in
* if (fail_count < UINT32_MAX - 1) below (or file foobar.c)
*/
uint32_t fail_count = 0;
With a proper encapsulation this should refer to exactly one place in the code.
Don't tell me you increment the fail count in many places. And if you do, what
about a
#define FAIL_COUNT_MAX UINT32_MAX
right next to the declaration? That's more proper and clean code anyway.
No need for all the assertion magic and rocket sciencery :-)
Is it possible to define a macro for the C preprocessor which takes an array as argument and expands to <type of array elements>_string? For example if x in an array of integers the macro invoked with argument x should expand to int_string.
I tried with
#define TypePaste(array) typeof(array[0])##_string
but it expands to )_string.
Even using multiple levels of indirection for the ## operand the macro doesn't expand correctly.
That's not possible. At the translation phase (the preprocessing phase) where macros are expanded and tokens are concatenated, the compiler (at this point, the preprocessor) does not yet have the notion of a type and thus cannot possibly generate types.
It is not all that clear what problem you are trying to solve, but given your comment:
the macro should expand to the name of an existing function. I'd like to define a function <type>_string for every existing type and then use the macro to select the right function according to the type of the array given.
Then you could use the C11 _Generic keyword:
#include <stdio.h>
void int_string (size_t size, int array[size])
{
printf("I am %s, do stuff here.\n", __func__);
}
void float_string (size_t size, float array[size])
{
printf("I am %s, do stuff here.\n", __func__);
}
#define TypePaste(array) \
_Generic( array, \
int: int_string, \
float: float_string ) \
(sizeof(array)/sizeof(*array), array) // function parameters
int main()
{
int i_arr[5];
float f_arr[3];
TypePaste(i_arr);
TypePaste(f_arr);
}
Output:
I am int_string, do stuff here.
I am float_string, do stuff here.
Note: this assumes that the passed parameter is a local/file scope allocated array. If passing a pointer, there's no type safety and the program will fail.
C11's _Generic type selection is the "proper" way to do what you want. There are other, platform dependent solutions, tough.
If you are using gcc – you don't say so eplicitly, but you use gcc's extension typeof already – you can use gcc's statement expresions and nested functions to create a comparison function for qsort on the spot:
double a[5] = {8.4, 8.1, 9.3, 12.2, 5.2};
qsort(a, 5, sizeof(*a), ({
int cmp(const void *p, const void *q) {
const typeof(a[0]) *pp = p;
const typeof(a[0]) *qq = q;
return (*pp < *qq) ? -1 : (*pp > *qq);
}
cmp;
}));
This creates a function and returns its address. (The last statement of a compound expression is its value. The scope of the local variables is the statement expression, but a nested function is not created on the stack so its safe to return a pointer to that function.)
For primitive types, where you want to sort according to the comparison operators < and >, you can turn that into a macro:
#define COMPARE(ARRAY)({ \
int cmp(const void *p, const void *q) { \
const typeof(ARRAY[0]) *pp = p; \
const typeof(ARRAY[0]) *qq = q; \
return (*pp < *qq) ? -1 : (*pp > *qq); \
} \
cmp; \
})
qsort(a, 5, sizeof(*a), COMPARE(a));
or even:
#define SORT(ARRAY, N) \
qsort(ARRAY, N, sizeof(*ARRAY), COMPARE(ARRAY))
SORT(a, 5);
That's not Standard C, so if you need compatibility between platforms, this is out of the question.
Is it possible to implement static_if in C99?
#define STATIC_IF(COND, ...) \
if (COND) MACRO1(__VA_ARGS__); \
else MACRO2(__VA_ARGS__);
How can I properly implement STATIC_IF(…) in here? Depending on COND the arguments either should be passed to MACRO1 or MACRO2, but the arguments for both macros look differently. COND is statically testable, something like sizeof (…) > 42.
#if COND then #define STATIC_IF MACRO1 … wouldn't work for my use case.
I cannot use compiler specific solutions.
In your specific case (if I understand your comments correctly), yes, you can do this.
You can't pass sizeof to anything in the preprocessor because the preprocessor runs before type information is available. Luckily for you, you don't need sizeof to count the number of arguments in a statically-written list (X-Y alert!), so this is no obstacle.
Here's one possible implementation using the Order macro library:
#include <stdio.h>
#include <order/interpreter.h>
void oneArg(int a) {
printf("one arg: %d\n", a);
}
void twoArgs(int a, int b) {
printf("two args: %d %d\n", a, b);
}
void threeArgs(int a, int b, int c) {
printf("three args: %d %d %d\n", a, b, c);
}
#define ORDER_PP_DEF_8function_list \
ORDER_PP_CONST(("unused") \
(oneArg) \
(twoArgs) \
(threeArgs))
#define SelectFunction(...) ORDER_PP ( \
8seq_at(8tuple_size(8((__VA_ARGS__))), 8function_list) \
)
#define Overloaded(...) SelectFunction(__VA_ARGS__)(__VA_ARGS__)
int main(void) {
Overloaded(42);
Overloaded(42, 47);
Overloaded(42, 47, 64);
return 0;
}
(This simple case indexes a list by the number of arguments - probably not exactly what you want to do, but enough to get the idea. Order does provide a full range of complex, nonevaluating control structures - if, cond, match, etc. - for more complex decision-making.)
Order is pretty heavyweight: I assume you can do something similar with the much lighter and more realistically-portable P99 (not familiar with it). Order works very well with GCC and adequately well with Clang (Clang will choke on deep recursion or long loops); it is standard, but not all compilers are.
This is not possible, because a condition like sizeof(something)>42 is not static for the preprocessor. The preprocessor is purely textual (in principle, except for arithmetic). It does not know about C or types.
Notice that expression of the condition in #if is severely constrained.
However, you could use build tricks. For instance, you might have a standalone program like
// generate-sizeof.c
#include <stdio.h>
#include "foo-header.h"
int main(int argc, char**argv) {
const char* headername = NULL;
if (argc<2)
{ fprintf(stderr, "%s: missing header name\n", argv[0]);
exit(EXIT_FAILURE); };
headername = argv[1];
FILE *fh = fopen(headername, "w");
if (!fh) { perror(headername); exit(EXIT_FAILURE); };
fprintf(fp, "// generated file %s\n", headername);
fprintf(fp, "#define SIZEOF_charptr %d\n", (int) sizeof(char*));
fprintf(fp, "#define SIZEOF_Foo %d\n", (int) sizeof(Foo));
fclose (fp);
}
then have a rule like
generated-sizes.h : generate-sizeof foo-header.h
./generate-sizeof generated-sizes.h
in your Makefile etc etc...
So your build machinery will generate the appropriate headers.
Things become much tricker if you want to cross-compile!
Then you might have an #include "generated-sizes.h" in your header, and later code
#if SIZEOF_Foo > 42
#error cannot have such big Foo
#endif
I don't think so, not in the sense you mean.
But: I would just go ahead, and trust that an optimizing compiler notices that the condition is always true (or false) and does the right thing, i.e. optimizes out the test.
You might need to force some optimization to provoke the compiler into doing this.
If you can remove the restriction of having to stick to C99, there is a better solution to this problem built-in to the language since C11:
#include <stdio.h>
void f1(float x, double y, float * z) {
printf("inside f1\n");
}
void f2(int x, _Bool * y) {
printf("inside f2\n");
}
#define STATIC_IF(COND, ...) _Generic(&(int[(!!(COND))+1]){ 0 }, \
int(*)[2]: f1, \
int(*)[1]: f2) \
(__VA_ARGS__)
int main(void) {
float fl;
_Bool b;
STATIC_IF(sizeof(double) > 4, 0.0f, 1.0, &fl);
STATIC_IF(sizeof(double) > 128, 16, &b);
}
The _Generic operator performs a compile-time selection based on a type. Since it selects based on a type, it's also the only language-level expression that can accept conflicting types of "argument", since its very purpose is to resolve a value of the right type based on inputs.
This means you can easily use it to choose between your two functions with incompatible signatures, because it will completely ignore the type of the one that isn't chosen by matching the input; the arguments (applied to whichever function _Generic returns) will only be checked against the successful match.
Although _Generic is designed to dispatch on types, not values, any integer constant expression can be "turned into" a type by using it as the size of an array. So in the above macro we create an anonymous array (n.b. this is not a VLA), of count either 2 (for true) or 1 (for false) and dispatch against the type of the pointer to that array in order to resolve which of the two incompatible functions to use.
This will certainly reduce to nothing at runtime, since not only is the condition static, but the alternative "execution path" wouldn't even type check and thus can't have code generated for it in the first place.
I have a function that I need to macro'ize. The function contains temp variables and I can't remember if there are any rules about use of temporary variables in macro substitutions.
long fooAlloc(struct foo *f, long size)
{
long i1, i2;
double *data[7];
/* do something */
return 42;
}
MACRO Form:
#define ALLOC_FOO(f, size) \
{\
long i1, i2;\
double *data[7];\
\
/* do something */ \
}
Is this ok? (i.e. no nasty side effect - other than the usual ones : not "type safe" etc). BTW, I know "macros are evil" - I simply have to use it in this case - not much choice.
There are only two conditions under which it works in any "reasonable" way.
The macro doesn't have a return statement. You can use the do while trick.
#define macro(x) do { int y = x; func(&y); } while (0)
You only target GCC.
#define min(x,y) ({ int _x = (x), _y = (y); _x < _y ? _x : _y; })
It would help if you explain why you have to use a macro (does your office have "macro mondays" or something?). Otherwise we can't really help.
C macros are only (relatively simple) textual substitutions.
So the question you are maybe asking is: can I create blocks (also called compound statements) in a function like in the example below?
void foo(void)
{
int a = 42;
{
int b = 42;
{
int c = 42;
}
}
}
and the answer is yes.
Now as #DietrichEpp mentioned it in his answer, if the macro is a compound statement like in your example, it is a good practice to enclose the macro statements with do { ... } while (0) rather than just { ... }. The link below explains what situation the do { ... } while (0) in a macro tries to prevent:
http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
Also when you write a function-like macro always ask yourself if you have a real advantage of doing so because most often writing a function instead is better.
First, I strongly recommend inline functions. There are very few things macros can do and they can't, and they're much more likely to do what you expect.
One pitfall of macros, which I didn't see in other answers, is shadowing of variable names.
Suppose you defined:
#define A(x) { int temp = x*2; printf("%d\n", temp); }
And someone used it this way:
int temp = 3;
A(temp);
After preprocessing, the code is:
int temp = 3;
{ int temp = temp*2; printf("%d\n", temp); }
This doesn't work, because the internal temp shadows the external.
The common solution is to call the variable __temp, assuming nobody will define a variable using this name (which is a strange assumption, given that you just did it).
This is mostly OK, except that macros are usually enclosed with do { ... } while(0) (take a look at this question for explanations):
#define ALLOC_FOO(f, size) \
do { \
long i1, i2;\
double *data[7];\
/* do something */ \
} while(0)
Also, as far as your original fooAlloc function returns long you have to change your macro to store the result somehow else. Or, if you use GCC, you can try compound statement extension:
#define ALLOC_FOO(f, size) \
({ \
long i1, i2;\
double *data[7];\
/* do something */ \
result; \
})
Finally you should care of possible side effects of expanding macro argument. The usual pattern is defining a temporary variable for each argument inside a block and using them instead:
#define ALLOC_FOO(f, size) \
({ \
typeof(f) _f = (f);\
typeof(size) _size = (size);\
long i1, i2;\
double *data[7];\
/* do something */ \
result; \
})
Eldar's answer shows you most of the pitfalls of macro programming and some useful (but non standard) gcc extension.
If you want to stick to the standard, a combination of macros (for genericity) and inline functions (for the local variables) can be useful.
inline
long fooAlloc(void *f, size_t size)
{
size_t i1, i2;
double *data[7];
/* do something */
return 42;
}
#define ALLOC_FOO(T) fooAlloc(malloc(sizeof(T)), sizeof(T))
In such a case using sizeof only evaluates the expression for the type at compile time and not for its value, so this wouldn't evaluate F twice.
BTW, "sizes" should usually be typed with size_t and not with long or similar.
Edit: As to Jonathan's question about inline functions, I've written up something about the inline model of C99, here.
Yes it should work as you use a block structure and the temp variables are declared in the inner scope of this block.
Note the last \ after the } is redundant.
A not perfect solution: (does not work with recursive macros, for example multiple loops inside each other)
#define JOIN_(X,Y) X##Y
#define JOIN(X,Y) JOIN_(X,Y)
#define TMP JOIN(tmp,__LINE__)
#define switch(x,y) int TMP = x; x=y;y=TMP
int main(){
int x = 5,y=6;
switch(x,y);
switch(x,y);
}
will become after running the preprocessor:
int main(){
int x=5,y=6;
int tmp9 = x; x=y; y=tmp9;
int tmp10 = x; x=y; y=tmp10;
}
They can. They often shouldn't.
Why does this function need to be a macro? Could you inline it instead?
If you're using c++ use inline, or use -o3 with gcc it will inline all functions for you.
I still don't understand why you need to macroize this function.