Skip to content

Instantly share code, notes, and snippets.

@vu3rdd
Last active January 23, 2019 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vu3rdd/ff0ddb881d9a23ce2d8b5f0ab709a952 to your computer and use it in GitHub Desktop.
Save vu3rdd/ff0ddb881d9a23ce2d8b5f0ab709a952 to your computer and use it in GitHub Desktop.
A simple C debug macro (needs a version of gcc compiler which supports the C11 standard)
/* Copyright 2019 Ramakrishnan Muthukrishnan
*
* To the extent possible under law, the author(s) have dedicated
* all copyright and related and neighboring rights to this software
* to the public domain worldwide. This software is distributed without
* any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software.
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#ifndef DBG_H_INCLUDED
#define DBG_H_INCLUDED 1
#if defined (__GNUC__)
#if defined (__STDC_VERSION__)
#if __STDC_VERSION__ >= 201112L
#include <stdio.h>
#define PRINTF_FMT_STR(x) _Generic((x), \
char: "%c", \
signed char: "%hhd", \
unsigned char: "%hhu", \
signed short: "%hd", \
unsigned short: "%hu", \
signed int: "%d", \
unsigned int: "%u", \
long int: "%ld", \
unsigned long int: "%lu", \
long long int: "%lld", \
unsigned long long int: "%llu", \
float: "%f", \
double: "%f", \
long double: "%Lf", \
char *: "%s", \
void *: "%p", \
bool: "%s" \
)
#define DBG(x) \
({ typeof (x) x_; \
x_ = (x); \
fprintf(stderr, "[%s:%d] %s = " , __FILE__, __LINE__, #x); \
fprintf(stderr, PRINTF_FMT_STR(x), x_); \
fprintf(stderr, "\n"); \
x_; \
})
#endif /* __STDC_VERSION >= XXXX */
#endif /* __STDC_VERSION__ */
#endif /* __GNUC__ */
#endif
@vu3rdd
Copy link
Author

vu3rdd commented Jan 21, 2019

Here is the version of factorial program example given in the Rust blog post:

fn factorial(n: u32) -> u32 {
    if dbg!(n <= 1) {
        dbg!(1)
    } else {
        dbg!(n * factorial(n - 1))
    }
}

And the output:

[src/main.rs:3] n <= 1 = false
[src/main.rs:3] n <= 1 = false
[src/main.rs:3] n <= 1 = false
[src/main.rs:3] n <= 1 = true
[src/main.rs:4] 1 = 1
[src/main.rs:5] n * factorial(n - 1) = 2
[src/main.rs:5] n * factorial(n - 1) = 6
[src/main.rs:5] n * factorial(n - 1) = 24
[src/main.rs:11] factorial(4) = 24

Here is the equivalent C version:

#include <stdio.h>
#include <stdbool.h>

#include "dbg.h"

int factorial(int n)
{
    if (DBG(n <= 1))
        return DBG(1);
    else
        return DBG(n * factorial(n - 1));
}

int main(void)
{
    int x = 4;
    
    DBG(factorial(x));
    return 0;
}

and the corresponding output:

$ gcc -Wall  foo.c && ./a.out
[foo.c:8] n <= 1 = 0
[foo.c:8] n <= 1 = 0
[foo.c:8] n <= 1 = 0
[foo.c:8] n <= 1 = 1
[foo.c:9] 1 = 1
[foo.c:11] n * factorial(n - 1) = 2
[foo.c:11] n * factorial(n - 1) = 6
[foo.c:11] n * factorial(n - 1) = 24
[foo.c:18] factorial(x) = 24

Thanks to Sajith for the inspiration and Olve Maudal for many suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment