在不使用结果的情况下将结构指针转换为 void 的目的
Purpose of casting a struct pointer to void without using the result
我正在尝试理解以下 C 代码。
static unsigned
parent(const struct binheap *bh, unsigned u)
{
(void)bh;
return (u / 2);
}
(void)bh;
的目的是什么?它没有分配给任何东西,也不应该对输出产生影响。我能想到的唯一目的可能是作为一种针对空指针的断言。
对于上下文,该片段来自 the original implementation of a B-heap。该代码在其他地方也往往过于聪明,例如for (unsigned n = 2; n; n += n) {
在 n = 65536 处中断。
这通常是为了避免编译器警告。例如,如果在 gcc
中使用 -Wall -Wextra
进行编译,它会警告您没有使用 bh
如果您不进行强制转换为 void.
这只是为了避免编译器针对未使用的变量发出警告。如果没有强制转换,您的编译器将(尝试)警告您代码中有一个未使用的变量。
(void)bh;
在生成的代码 中没有效果。但是,对于许多编译器,它会阻止编译器发出有关参数 bh
未在函数中以其他方式使用的警告,这几乎可以肯定是程序员的意图。 bh
是一个结构指针是无关紧要的;如果此技术完全有效,则无论未使用参数的类型如何,它都会起作用。
C++ 有一种更优雅的方法来实现这一点,允许您省略不需要的任何参数的变量名 --
static unsigned
parent(const struct binheap *, unsigned u)
{
return (u / 2);
}
-- 但是 C 不支持这个。一些编译器出于相同的目的进行了扩展,即使不是那么优雅,至少也更具自我描述性,例如海湾合作委员会
static unsigned
parent(const struct binheap *bh __attribute__((unused)), unsigned u)
{
return (u / 2);
}
(void)bh;
技巧是唯一一种仅使用 ISO C 功能来抑制未使用参数警告的技术;另一方面,它不能保证工作,编译器发出的警告完全取决于该编译器,因此无论您做什么,您都已经处于实现定义的领域。
因为编译器警告
有些编译器会在函数中未使用变量时发出警告。见下文
#include <stdio.h>
void hello(int a, int b)
{
int i = b + 1;
printf("hello %d\n", i);
return;
}
int main(void)
{
hello(10, 20);
return 0;
}
如下所示编译它以查看警告
$ gcc -Wunused-parameter a.c
a.c:3:16: warning: unused parameter 'a' [-Wunused-parameter]
void hello(int a, int b)
^
1 warning generated.
我正在尝试理解以下 C 代码。
static unsigned
parent(const struct binheap *bh, unsigned u)
{
(void)bh;
return (u / 2);
}
(void)bh;
的目的是什么?它没有分配给任何东西,也不应该对输出产生影响。我能想到的唯一目的可能是作为一种针对空指针的断言。
对于上下文,该片段来自 the original implementation of a B-heap。该代码在其他地方也往往过于聪明,例如for (unsigned n = 2; n; n += n) {
在 n = 65536 处中断。
这通常是为了避免编译器警告。例如,如果在 gcc
中使用 -Wall -Wextra
进行编译,它会警告您没有使用 bh
如果您不进行强制转换为 void.
这只是为了避免编译器针对未使用的变量发出警告。如果没有强制转换,您的编译器将(尝试)警告您代码中有一个未使用的变量。
(void)bh;
在生成的代码 中没有效果。但是,对于许多编译器,它会阻止编译器发出有关参数 bh
未在函数中以其他方式使用的警告,这几乎可以肯定是程序员的意图。 bh
是一个结构指针是无关紧要的;如果此技术完全有效,则无论未使用参数的类型如何,它都会起作用。
C++ 有一种更优雅的方法来实现这一点,允许您省略不需要的任何参数的变量名 --
static unsigned
parent(const struct binheap *, unsigned u)
{
return (u / 2);
}
-- 但是 C 不支持这个。一些编译器出于相同的目的进行了扩展,即使不是那么优雅,至少也更具自我描述性,例如海湾合作委员会
static unsigned
parent(const struct binheap *bh __attribute__((unused)), unsigned u)
{
return (u / 2);
}
(void)bh;
技巧是唯一一种仅使用 ISO C 功能来抑制未使用参数警告的技术;另一方面,它不能保证工作,编译器发出的警告完全取决于该编译器,因此无论您做什么,您都已经处于实现定义的领域。
因为编译器警告
有些编译器会在函数中未使用变量时发出警告。见下文
#include <stdio.h>
void hello(int a, int b)
{
int i = b + 1;
printf("hello %d\n", i);
return;
}
int main(void)
{
hello(10, 20);
return 0;
}
如下所示编译它以查看警告
$ gcc -Wunused-parameter a.c
a.c:3:16: warning: unused parameter 'a' [-Wunused-parameter]
void hello(int a, int b)
^
1 warning generated.