【问题标题】:Why can't we define a function using a type name?为什么我们不能使用类型名称定义函数?
【发布时间】:2016-03-28 02:40:35
【问题描述】:

关于为什么我们不能使用类型名称定义函数的任何想法:

typedef int functype(int arg1);


functype funcdefinition {
    ;
}

但我们可以这样声明:

functype funcdeclaration;

【问题讨论】:

  • 参数名会去哪里?
  • @M.M 它们将从类型名称继承。我非常怀疑这是否难以实施。
  • 如果用于声明函数的类型名称没有为某些参数分配名称,则该参数将无法通过名称访问,就像未命名的临时参数一样。
  • 否则编译器会报错。

标签: c function types language-lawyer c11


【解决方案1】:

标准规定(C11 第 6.9.1 节):

函数定义中声明的标识符(即函数的名称)应具有函数类型,由函数定义的声明符部分指定162)

脚注 162 说:

162) 意图是函数定义中的类型类别不能从 typedef 继承:

typedef int F(void);          // type F is ‘‘function with no parameters 
                              // returning int’’
F f,g;                        // f and g both have type compatible with F   
F f { /* ... */ }             // WRONG: syntax/constraint error  
F g() { /* ... */ }           // WRONG: declares that g returns a function   
int f(void) { /* ... */ }     // RIGHT: f has type compatible with F  
int g() { /* ... */ }         // RIGHT: g has type compatible with F
F *e(void) { /* ... */ }      // e returns a pointer to a function
F *((e))(void) { /* ... */ }  // same: parentheses irrelevant
int (*fp)(void);              // fp points to a function that has type F   
F *Fp;                        // Fp points to a function that has type F

因此,

functype funcdefinition;  

声明funcdefinitionfunctype 类型,这是正确的。函数原型中不需要函数参数的名称。如果发生

functype funcdefinition { ... }    

需要参数名称,无法声明函数参数的名称,因此语法不正确。

【讨论】:

  • 是的,有什么想法为什么会这样?我的意思是使用类型名称来定义函数有什么问题?
  • @FISOCPP 很可能只是他们认为没有任何理由让它发挥作用。
  • @FISOCPP;为答案添加了解释。
【解决方案2】:

您可以为函数原型定义 typedef,但不能为函数体。

functype(在上面的问题中)的 typedef 是为函数原型创建 typedef - 而不是函数体。在“C”语言中,包含函数体的函数不会评估为有效类型。这就是为什么不允许使用函数体的原因。

为什么 C 语言不允许类型包含函数体?因为:

  • 当对函数体类型使用精确类型检查时,只有 匹配functype 的类型与funcdefinition 具有相同的体
  • 通过精确类型检查,函数体数据类型只能指向具有完全相同代码的函数。
  • 如果在类型定义中使用了函数体,那么即使是具有相同原型(但不同的主体)的函数在技术上也会导致类型不匹配。当前版本的“C”是强类型的。因为“C 和 C++ (do) 不允许您在需要另一种类型时使用一种类型。”,即使 C 编译器在类型定义中包含函数体(它没有),编译器也无法解决函数体中的差异,而不是报告类型不匹配。


虽然它不如使用带有主体的 typedef 有用,但您仍然可以使用此 typedef 创建一个 函数指针 - C++ 编译器仍会检查参数列表;见下文:

typedef int functype(int arg1);

int f1(int arg1) {
    return arg1;
}
int f2(int arg1) {
    return arg1;
}
int f3(int arg1, int arg2) {
    return 0;
}
int main(int argc, char* argv[])
{
    functype* pf1;
    pf1=&f1;           /* Compiles properly */
    pf1=&f3;           /* Will not compile, as expected */
                       /* because of an argument mismatch */
    return 0;
}

从这个意义上说,使用 typedef 是有帮助的,因为它避免了函数指针语法。

参考:

http://www.drtak.org/teaches/modules/0027/module/node7.html

【讨论】:

    【解决方案3】:

    当你定义一个函数时

    xxx myfunction(...) {}
    

    您说 myfunction 是一个返回 xxx 的函数。例如,

    int myFunc()[]
    

    表示 myFunc 返回一个 int。因此

    functype funcdefinition() { ... }  
    

    说funcdefinition返回一个functype,这(如果你的例子是正确的)意味着它返回“一个接受整数参数并返回一个int的函数”。

    【讨论】:

    • 你没有回答我的问题,基本上是在说题外话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    相关资源
    最近更新 更多