C / C ++:调用没有参数的函数,函数不返回任何内容

时间:2010-01-27 01:11:07

标签: c++ c

为什么不能调用一个不带参数的函数调用函数调用作为不返回任何值的参数(IMHO相当于调用一个不带参数的参数的函数)。

例如:

void foo(void) {...}
void bar(void) {...}

foo(bar())

不要误解我的意思,我知道void不是一个值,并且它不能被视为一个。

凭借我的逻辑,这将是有道理的,应该可以做到这一点。 我的意思是,为什么不呢?任何争论为什么不可能?

9 个答案:

答案 0 :(得分:8)

我不相信我听过的任何理由都是好的。

请参阅在C ++中,您可以返回void函数的结果:

void foo() {
    // ...
}

void bar() {
    // ...
    return foo();
}

是的,它完全相同:

foo();
return;

但与通用编程更加一致,因此您可以使转发功能工作,而不必担心转发的函数是否有void返回。

因此,如果应用类似的系统使得void返回在函数组合场景中构成一个无效调用,那么这可能会使函数组合更通用。

答案 1 :(得分:3)

因为,根据标准第3.9.1 / 9段,

  

这是   应使用void类型的表达式   仅作为表达式声明(6.2),   作为逗号表达式的操作数   (5.18),作为第二或第三操作数   ?:( 5.16),作为的操作数   typeid,或作为a中的表达式   返回声明(6.6.3)a   函数返回类型为void。

C / C ++只是不是那种通用的。你得到return returns_void();进行尾调用优化,那是功能性的,对吧? :的vP

修改:上述规则仍允许您在takes_void(3)转换为3的情况下致电void。这是禁止的8.3.5 / 2:

  

如果参数声明子句是   空的,功能不需要   参数。参数列表(void)   相当于空参数   名单。除了这个特殊情况,   void不应是参数类型   (尽管类型来自void,例如   as void *,can)。

答案 2 :(得分:2)

如果使用C / C ++中的所有其他参数列表统一处理(void)参数列表,则语义意味着此类参数声明是“类型void的单个参数”。如果是这种情况,那么为了统一的目的,很可能语言允许将调用“链接”到如示例中所示的函数。 (至少C ++可能会,因为它允许return语句中的这种统一性。)

但是,在C ++语言和C语言中,具有(void)形式的参数列表不会与其他形式的参数列表统一处理。相反,它具有特殊意义。这意味着该函数没有任何参数。 (相当于C ++中的空())。

换句话说,用(void)参数列表声明的函数采用参数。您正在提供一个。这是非法的。考虑到C / C ++中(void)参数列表的特殊含义,允许

foo(bar());

与允许

没有太大区别
foo(bar(), bar());
foo(bar(), bar(), bar());

也是。定性地,2和3与0有很大不同,因为1是。

答案 3 :(得分:2)

不要被符号误导。相反令人讨厌的是,C使用f(void)原型来表示“f期望没有参数”,而不是“f期望单个void类型的参数”。符号f()保持为“f期望的参数数量未知,因此您可以使用任意数量的参数调用它,并祝您好运”。在ANSI标准C(又名C89)之前,没有函数原型这样的东西,你需要像lint这样的工具来保护你免受参数的最普通的错误,例如传递错误的数字参数或传递具有非常不兼容类型的参数。

至于为什么你不能使用函数返回void的值作为值,或者为什么你不能将参数传递给不需要参数的函数,这些限制就是为了保护你用参数制作最普通的错误。

答案 4 :(得分:1)

它确实有道理(bar不产生任何内容,foo不消耗任何内容,因此应允许foo(bar())。 OTOH,只会让读者感到困惑。如果你想成为l33t,总会有,&&||运算符来模拟分号。

答案 5 :(得分:0)

因为void不允许您指定参数名称,这是为了捕获第一个函数的返回值所必需的,无论它实际返回什么。

答案 6 :(得分:0)

让我们假装它有效。你能想到一个假设的案例

bar();
foo();

完全相同的东西是不是更具可读性和合理性?

编辑。是的是的。 :)

答案 7 :(得分:0)

  

目前我的代码中有这样的东西:#define EVAL(f)f(++ evalcounter)不要问我为什么使用它,我只需要。通常f不带任何值。我刚刚添加了这个(全局)整数来计算一些东西。如果我有像#define EVAL(f)f(dummy(++ evalcounter))这样的东西会不会更好?

您是否尝试过逗号运算符:

#define EVAL(f)   (++evalcounter, f())

答案 8 :(得分:0)

我将添加一个额外的声明:void baz(int);

现在很明显,如果类型为void的参数等于无参数,则两个参数(其中一个类型为void)将等于一个参数(因为0 = 1 * x< => 1 = 1 + 1 * x)

所以,显然这是合法的:baz(1, bar());。但也(因为虚空是“没有”)baz(bar(),1);

我们可以从这个意义上继续:baz(bar(), 1, bar());。毕竟,“无效就是虚无”。

要么你完全禁止它,施加任意限制,要么你最终允许荒谬的结构。我同意第一项决议的选择