在 C 中使用 makefile 标志进行调试
Debugging using makefile flags in C
我需要设置一种方法来从 make 文件中调试我的程序。具体来说,当我输入 make -B FLAG=-DNDEBUG
时,我需要程序正常地 运行。但是当这个标志不存在时,我需要在整个代码中使用一些 assert()
命令到 运行.
为了澄清,我需要知道如何检查我的 C 代码中是否不存在此标志,我假设它与 #ifndef
有关,我只是不知道在哪里从那里开始。
原谅我的无知,如有回复将不胜感激!
无论是否使用 "FLAG=-DNDEBUG" 调用 make 时,您的 Makefile 中都需要这样的规则:
%.o: %.c
gcc -c $(FLAG) $<
在您的 C 代码中,您需要这样的东西:
#ifndef NDEBUG
fprintf(stderr, "My trace message\n");
#endif
假设您正在谈论标准库中的 assert
宏(<assert.h>
中的 #define
d),那么您无需执行任何操作。该库已经处理了 NDEBUG
标志。
如果您想让自己的代码仅在宏是/不是 #define
d 时执行操作,请使用您在问题中已经怀疑的 #ifdef
。
例如,我们可能有一个条件太复杂而无法放入单个 assert
表达式中,因此我们需要一个变量。但是如果 assert
展开为空,那么我们不希望计算该值。所以我们可能会使用这样的东西。
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;
}
请注意,这种编码风格会导致代码难以阅读,并且要求 Heisenbugs 极难调试。更好的表达方式是使用函数。
/* 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;
}
我需要设置一种方法来从 make 文件中调试我的程序。具体来说,当我输入 make -B FLAG=-DNDEBUG
时,我需要程序正常地 运行。但是当这个标志不存在时,我需要在整个代码中使用一些 assert()
命令到 运行.
为了澄清,我需要知道如何检查我的 C 代码中是否不存在此标志,我假设它与 #ifndef
有关,我只是不知道在哪里从那里开始。
原谅我的无知,如有回复将不胜感激!
无论是否使用 "FLAG=-DNDEBUG" 调用 make 时,您的 Makefile 中都需要这样的规则:
%.o: %.c
gcc -c $(FLAG) $<
在您的 C 代码中,您需要这样的东西:
#ifndef NDEBUG
fprintf(stderr, "My trace message\n");
#endif
假设您正在谈论标准库中的 assert
宏(<assert.h>
中的 #define
d),那么您无需执行任何操作。该库已经处理了 NDEBUG
标志。
如果您想让自己的代码仅在宏是/不是 #define
d 时执行操作,请使用您在问题中已经怀疑的 #ifdef
。
例如,我们可能有一个条件太复杂而无法放入单个 assert
表达式中,因此我们需要一个变量。但是如果 assert
展开为空,那么我们不希望计算该值。所以我们可能会使用这样的东西。
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;
}
请注意,这种编码风格会导致代码难以阅读,并且要求 Heisenbugs 极难调试。更好的表达方式是使用函数。
/* 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;
}