【问题标题】:Can a formal parameter have the same name as a type? (C)形式参数可以与类型同名吗? (C)
【发布时间】:2020-03-22 06:27:23
【问题描述】:

我并不是说这是一种好的编程风格,但令我惊讶的是,它已编译 [*] 并毫无怨言地运行:

#include <stdio.h>

// define function signature
typedef int (*proto_fn)();

int x() { return 22; }

// Note: type name and formal parameter name are the same
void printit(proto_fn proto_fn) { 
  printf("%d\n", proto_fn());
}

int main() {
  printit(x);
  return 0;
}

除了可能使人类感到困惑之外,C 标准中是否有任何内容禁止对类型和形参使用相同的名称?

[*](在本例中为 Apple clang 版本 11.0.0 (clang-1100.0.33.8)。)

【问题讨论】:

  • 我认为这与 K 或 R 写的著名的问题有关:“大家都同意这里的冰很薄。”
  • 函数参数定义后,该函数中的名称proto_fn不再是类型而是变量,因此不能使用类型名称proto_fn声明另一个指向函数的指针函数的主体。顺便提一下,指针不是原型的——不是严格的原型。函数的参数数量是固定的,而不是可变的,但类型是未指定的。使用typedef int (*proto_fn)(void); 为不带参数的函数提供原型。 (x()main() 的定义都没有提供原型。)
  • 使用-Wshadow 来获取有关隐藏变量和类型的警告。注意警告。但你所做的是合法的——不可取,但合法。
  • @JonathanLeffler:“请注意,指针不是......严格原型化。......使用typedef int (*proto_fn)(void); 为不带参数的函数提供原型。”归档在“我今天学到的一件新事物”下——谢谢。

标签: c typedef


【解决方案1】:

我修改了代码以检查名称proto_fn是代表类型名称还是代表proto_fn类型的变量,在函数printit内部。

#include <stdio.h>

// define function signature
typedef int (*proto_fn)();

int x() { return 22; }

// Note: type name and formal parameter name are the same
void printit(proto_fn proto_fn) 
{ 
  printf("%d\n", proto_fn());
  proto_fn;

}

int main() {
  printit(x);
  return 0;
}

以上代码运行良好。

#include <stdio.h>

// define function signature
typedef int (*proto_fn)();

int x() { return 22; }

// Note: type name and formal parameter name are the same
void printit(proto_fn proto_fn) 
{ 
  printf("%d\n", proto_fn());
  proto_fn kk;

}

int main() {
  printit(x);
  return 0;
}

但是这段代码会抛出错误:
error: expected ‘;’ before ‘kk’
proto_fn kk;

因此,由此我得出结论,名称proto_fn 只是函数printit 内的proto_fn 类型的变量。我认为 proto_fn 类型在函数 printit 内不可见。我认为变量proto_fn 会在函数printit 中隐藏类型proto_fn。这可能是代码有效的原因。

【讨论】:

  • 没错。正如@Jonathan-Leffler 上面评论的那样:“定义函数参数后,该函数中的名称 proto_fn 不再是类型而是变量,因此您不能在主体中使用类型名称 proto_fn 声明另一个指向函数的指针函数。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多