0

I need to set up a way to debug my program from the make file. Specifically, when I type make -B FLAG=-DNDEBUG I need the program to run normally. But when this flag is not present I need a few assert() commands throughout the code to run.

To clarify I need to know how to check if this flag is not present from within my C code, I'd assume it has something to do with #ifndef, I just don't know where to go from there.

Forgive my ignorance, any response would be greatly appreciated!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
PresumablyZach
  • 99
  • 3
  • 12

2 Answers2

0

When calling make with or without "FLAG=-DNDEBUG" you will need rules like this in your Makefile:

%.o: %.c gcc -c $(FLAG) $<

In your C code you will need something like this:

#ifndef NDEBUG
  fprintf(stderr, "My trace message\n");
#endif
Henrik Carlqvist
  • 1,138
  • 5
  • 6
0

Assuming you are talking about the assert macro from the standard library (#defined in <assert.h>) then you don't have to do anything. The library already takes care of the NDEBUG flag.

If you want to make your own code do things only if the macro is / is not #defined, use an #ifdef as you already suspect in your question.

For example, we might have a condition that is too complex to put into a single assert expression so we want a variable for it. But if the assert expands to nothing, then we don't want that value computed. So we might use something like this.

int
questionable(const int * numbers, size_t length)
{
#ifndef NDEBUG
  /* Assert that the numbers are not all the same. */
  int min = INT_MAX;
  int max = INT_MIN;
  size_t i;
  for (i = 0; i < length; ++i)
    {
      if (numbers[i] < min)
        min = numbers[i];
      if (numbers[i] > max)
        max = numbers[i];
    }
  assert(length >= 2);
  assert(max > min);
#endif
  /* Now do what you're supposed to do with the numbers... */
  return 0;
}

Be warned that this coding style makes for hard to read code and is asking for Heisenbugs that are extremely difficult to debug. A much better way to express this is to use functions.

/* 1st helper function */
static int
minimum(const int * numbers, size_t length)
{
  int min = INT_MAX;
  size_t i;
  for (i = 0; i < length; ++i)
    {
      if (numbers[i] < min)
        min = numbers[i];
    }
  return min;
}

/* 2nd helper function */
static int
maximum(const int * numbers, size_t length)
{
  int max = INT_MIN;
  size_t i;
  for (i = 0; i < length; ++i)
    {
      if (numbers[i] > max)
        max = numbers[i];
    }
  return max;
}

/* your actual function */
int
better(const int * numbers, int length)
{
  /* no nasty `#ifdef`s */
  assert(length >= 2);
  assert(minimum(numbers, length) < maximum(numbers, length));
  /* Now do what you're supposed to do with the numbers... */
  return 0;
}
5gon12eder
  • 24,280
  • 5
  • 45
  • 92