How to check `typeof` for void value at compile time?

typescript null check operator
c typeof
typescript undefined'; check
typescript non-null assertion operator

let's say that I want to have C macro that works on any type. I'm using GCC compiler (>= 4.6) and can use GNU99 macros.

//code...
any_type_t *retVal = function_that_runs_very_long_time(a, b, &&c, **d, &e, *f);
//other code...

usage of macro for TIMER can look for example like this

//code...
any_type_t *retVal = 
    TIMER(
          function_that_runs_very_long_time(a, b, &&c, **d, &e, *f),
          "TIMING FOR VALUE <%d, %d>", a, b
         );
//other code...

So TIMER has to return value of given function and print duration of its run. There is problem with functions that have void return type.

I can obviously have two macros like TIMER_TYPE and TIMER_VOID, but I want to use single one to time function with any return value.

Thank you for suggestions.


Edited example of this TIMER macro

#define TIMER(expr, fmt_msg, ...)                           \
({                                                          \
    struct timeval before, after;                           \
    uint64_t time_span;                                     \
    int time_span_sec, time_span_usec;                      \
    gettimeofday(&before, NULL);                            \
    typeof(expr) _timer_expr__ = (expr);                    \ // <- static if?
    gettimeofday(&after, NULL);                             \
    time_span = (after.tv_sec * 1000000 + after.tv_usec)    \
              - (before.tv_sec * 1000000 + before.tv_usec); \
    time_span_sec  = time_span / 1000000;                   \
    time_span_usec = time_span % 1000000;                   \
    TRACE(fmt_msg "\n%s : %d.%d seconds",                   \
          #expr, time_span_sec, time_span_usec, ...);       \
    _timer_expr__;                                          \
})

What an interesting question, kudos!

After few experiments, I found a solution which uses __builtin_types_compatible_p and __builtin_choose_expr intrinsics of GCC.

__builtin_types_compatible_p

Quoting GCC manual:

Built-in Function: int __builtin_types_compatible_p (type1, type2)

You can use the built-in function __builtin_types_compatible_p to determine whether two types are the same.

This built-in function returns 1 if the unqualified versions of the types type1 and type2 (which are types, not expressions) are compatible, 0 otherwise. The result of this built-in function can be used in integer constant expressions.

This built-in function ignores top level qualifiers (e.g., const, volatile). For example, int is equivalent to const int.

So here is how we can check for "voidness".

#define __type_is_void(expr) __builtin_types_compatible_p(typeof(expr), void)
__builtin_choose_expr

Built-in Function: type __builtin_choose_expr (const_exp, exp1, exp2)

You can use the built-in function __builtin_choose_expr to evaluate code depending on the value of a constant expression. This built-in function returns exp1 if const_exp, which is an integer constant expression, is nonzero. Otherwise it returns exp2.

This built-in function is analogous to the ? : operator in C, except that the expression returned has its type unaltered by promotion rules. Also, the built-in function does not evaluate the expression that is not chosen. For example, if const_exp evaluates to true, exp2 is not evaluated even if it has side-effects.

If exp1 is returned, the return type is the same as exp1's type. Similarly, if exp2 is returned, its return type is the same as exp2.

So __builtin_choose_expr intrinsic is something like a "static switch" evaluated at compile-time.

Preparation

I don't paste here your TIMER macro, but I assume it is able to split it into two versions: one for void expr and one for the rest. Here are just stubs which evaluate the expression and yield the result of the same type.

#define __DO(expr) \
    ({ typeof(expr) __ret; __ret = (expr); __ret; })

#define __DO_VOID(expr) \
    (void) (expr)
Naive solution

Now we can statically switch between two implementations, depending on the actual type of the expression. But in fact the naive solution doesn't work, see below.

#define DO(expr) \
    __builtin_choose_expr(__type_is_void(expr), \
        __DO_VOID(expr), \
        __DO(expr))  # won't work

Attempt to compile this code passing a void expression gives the following error:

test.c:28:9: error: variable or field ‘__ret’ declared void
test.c:28:9: error: void value not ignored as it ought to be

Although __DO_VOID is chosen, __DO generates errors. This behavior is described in manual:

... the unused expression (exp1 or exp2 depending on the value of const_exp) may still generate syntax errors. This may change in future revisions.

Working solution

The trick is to substitute the original void expr with some non-void value to be able to compile the __DO case (which is anyway a dead code when expr is void).

#define __expr_or_zero(expr) __builtin_choose_expr(__type_is_void(expr), 0, (expr))

#define DO(expr) \
    __builtin_choose_expr(__type_is_void(expr), \
        __DO_VOID(expr), \
        __DO(__expr_or_zero(expr))) # works fine!

That's it! Here is the complete source code on Ideone: http://ideone.com/EFy4pE

How to use typeof, statement expressions and Block-scope label , New Language Extensions in the Oracle Developer Studio C Compiler. Library​, support arbitrary data types and provide strict compile-time type-checking. has type void if the last statement is not an expression that returns a value. The first  //code any_type_t *retVal = TIMER(function_that_runs_very_long_time(a, b, &&c, **d, &e, *f), "TIMING FOR VALUE <%d, %d>", a, b); //other code So TIMER has to return value of given function and print duration of its run. There is problem with functions that have void return type.


can you accept an answer of "this isn't really possible" ?

not the part about returning from a macro. but the part about conditionally testing expr for its return type.

in effect, you're asking for something like the following:

let's say instead of some magical check called "is_expr_type_void(expr)", you instead simply pass a 1 or a 0 at the time of the call to indicate is_void or !is_void in the following variation of your macro:

#define TIMER(is_void, expr, fmt_msg, ...)                  \
({                                                          \
    struct timeval before, after;                           \
    uint64_t time_span;                                     \
    int time_span_sec, time_span_usec;                      \
    gettimeofday(&before, NULL);                            \
    if (is_void)                                            \
        (expr)                                              \
    else                                                    \
        typeof(expr) _timer_expr__ = (expr);                \ // <- static if?
    gettimeofday(&after, NULL);                             \
    time_span = (after.tv_sec * 1000000 + after.tv_usec)    \
              - (before.tv_sec * 1000000 + before.tv_usec); \
    time_span_sec  = time_span / 1000000;                   \
    time_span_usec = time_span % 1000000;                   \
    TRACE(fmt_msg "\n%s : %d.%d seconds",                   \
          #expr, time_span_sec, time_span_usec, ...);       \
    if (!is_void)                                           \
        _timer_expr__;                                      \
})

this simply cannot work. the preprocessor would create code for that if-else conditional in all cases, both void and non-void function calls. and both sides would compile fine for non-void functions. but the compiler would always choke on the "else" part of the conditional when TIMER is invoked with a void function … despite the fact that the code would never be called.

(now if there existed a really smart compiler that could both identify that it would be dead code and dead-strip it prior to flagging it as a compile time error, you'd be in luck! but i don't think gcc 4.6 is that smart … )

this leaves you with what would be a preferred option of a #if (is_void) conditional inside the #define. but that's simply not allowed. since, as this answer points out in attempting to answer a similar question about conditional preprocessing, the preprocessor is not turing-complete.

so … despite your desire to have a single macro, i think your simplest answer is to create one for void functions, and one for functions with return values.

The C# Programming Language, public class Dictionary<K,V> { public void Add(K key, V value) { if (key. Although this solution works, it requires a dynamic type check at runtime, which adds  I'm trying to wrap the Windows API functions to check errors when I so choose. As I found out in a previous SO question, I could use a template function to call the API function, and then call


As long as you've got typeof and _Generic, you can do also do it without __builtin_types_compatible_p or __builtin_choose_expr.

The caveat is that _Generic won't let you match void so instead of matching Expr against void, match (typeof(Expr)*){0} against void*.

Below is eldar-abusalimov example modified to use _Generic instead of __builtin_types_compatible_p and __builtin_choose_expr:

#include <stdio.h>
#define __type_is_void(expr) _Generic((typeof(expr)*){0}, void*:1, default:0)
#define __expr_or_zero(expr) _Generic((typeof(expr)*){0}, void*:0, default:(expr))

#define DO(expr) \
    _Generic((typeof(expr)*){0}, \
        void*:__DO_VOID(expr), \
        default:__DO(__expr_or_zero(expr)))

#define __DO(expr) \
    ({ typeof(expr) __ret; puts("do nonvoid"); __ret = (expr); __ret; })

#define __DO_VOID(expr) \
    (void)({ puts("do void"); (void)(expr); })

void foo(void) { }
int bar(void) { return 1; }

int main(void) 
{
    DO(foo());
    DO(bar());
    return 0;
}

Perspectives of System Informatics: Third International Andrei , Since all used data types are known at compile time, the compiler can instantiate The type checking of any operation concerning a Value object is performed by sin(double); a function with this signature must exist void apply(list<Value>  Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more I need to do a compile time check whether the current function has a void return type or not and fail compilation if the return t


If you really need to return from macro, use inline function instead.

5. Compile Time Techniques in C++, Type-to-Type Mapping: map types to lightweight types at compile time and Inheritance: at compile time, determine if a tyope can convert to another type The type remains in the namespace after the function returns, so objects of the locally template <typename T, int isPolymorphic> class NiftyContainer { private: void  Use typeof when you want to get the type at compilation time. Use GetType when you want to get the type at execution time. There are rarely any cases to use is as it does a cast and, in most cases, you end up casting the variable anyway. There is a fourth option that you haven't considered (especially if you are going to cast an object to the


Nim Manual, Most of the Nim language is supported at compile time, but there are some A constant expression is an expression whose value can be computed during nil, void: # leaf type: kinds identical; nothing more to check result = true of ref, ptr, var,​  I know that methods declared with void does not return anything.. But it seems that in C# void is more then just a keyword, but a real type. void is an alias for System.Void like int that is for System.Int32.


Handbook - TypeScript 2.0, A property access or a function call produces a compile-time error if the object or function test(x: string | null) { if (x === null) { return; } x; // type of x is string in this: void means that addClickListener expects onclick to be a function that does  The expression typeof x always expects x to be a value, but typeof x itself could be a value or type depending on the context: let bar = {a: 0}; let TypeofBar = typeof bar; // the value "object" type TypeofBar = typeof bar; // the type {a: number}


Runtime and compile , value is a closure expression which has access to a special variable node 3, it can be used to perform assertions at compile time Imagine, for example, that you want to test the declared type of a for loop variable. int_TYPE }) void someMethod() { int x = 1; int y = 10; anchor: for (int i=0;  If you need to ensure that the value is an array (then cause a compile time error if not), you can simply use it as an initializer to an enum statement (or a static variable), like this: static int __ ## arg ## _is_array = IS_ARRAY(arg); // works for an array, fails for pointer.