简体   繁体   English

在C中使用makefile标志进行调试

[英]Debugging using makefile flags in C

I need to set up a way to debug my program from the make file. 我需要设置一种从make文件调试程序的方法。 Specifically, when I type make -B FLAG=-DNDEBUG I need the program to run normally. 具体来说,当我输入make -B FLAG=-DNDEBUG我需要程序正常运行。 But when this flag is not present I need a few assert() commands throughout the code to run. 但是,当不存在此标志时,我需要在整个代码中运行一些assert()命令。

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. 为了澄清,我需要知道如何从我的C代码中检查是否不存在该标志,我假设它与#ifndef ,我只是不知道从那里去。

Forgive my ignorance, any response would be greatly appreciated! 原谅我的无知,任何回应将不胜感激!

When calling make with or without "FLAG=-DNDEBUG" you will need rules like this in your Makefile: 在调用带有或不带有“ FLAG = -DNDEBUG”的make时,您的Makefile中将需要以下规则:

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

In your C code you will need something like this: 在您的C代码中,您将需要以下内容:

#ifndef NDEBUG
  fprintf(stderr, "My trace message\n");
#endif

Assuming you are talking about the assert macro from the standard library ( #define d in <assert.h> ) then you don't have to do anything. 假设您正在谈论标准库(在<assert.h> #define d)中的assert宏,那么您无需执行任何操作。 The library already takes care of the NDEBUG flag. 该库已经处理了NDEBUG标志。

If you want to make your own code do things only if the macro is / is not #define d, use an #ifdef as you already suspect in your question. 如果只在宏不是/ #define d的情况下才使自己的代码执行操作,请使用#ifdef因为您已经在问题中怀疑了。

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. 例如,我们的条件可能太复杂而无法放入单个assert表达式中,因此我们需要一个变量。 But if the assert expands to nothing, then we don't want that value computed. 但是,如果assert扩展为空,则我们不希望计算该值。 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. 请注意,这种编码风格会使代码难以阅读,并且要求调试非常困难的Heisenbug 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM