函数原型范围的实际应用或价值
Practical Applications or Value of Function Prototype Scope
首先:在搜索答案时,我可以[标记]要搜索的区域。这个发帖界面应该也支持吧
除了只需要类型而不需要标识符的错误检查之外,利用函数原型作用域可能会遇到哪些实际应用?这有什么好处?
function(int index, float array[index]);
//function prototype with names
对
function(int, float);
//function prototype(without identifiers)...
函数的定义总是包括 return 参数、函数名称和函数参数,包括类型和名称似乎具有原型作用域是多余的,因为参数无论如何都用名称重新声明:
原型:
return_type return_name(argument_type, ...);
函数声明:
return_type return_name(argument_type argument_name, ...){
compound_statement_function_block;
}
我能看到的唯一价值是它在文件范围名称中保留了函数名称space,这意味着函数名称可以在原型中使用:
int func(int func); //Proto type declaration. Compiler allows this
//but throws warning about func() redeclaration
//but nothing about the arguments.
int function(int function){
int function;
}
我原以为作用域与名称无关,意思是 file_scope_variable_name 不同于 file_scope_function_name。它们在上下文和显着差异上足以成为这样,我认为这就是标准所要求的,但是我使用的编译器 gcc 不允许这样做。但是,它将允许在任何范围内将 main 重新声明为 struct/union 名称 space 中的标记,因为它们是像函数这样的块元素:
int func(int func){
typedef struct {
int func;
}; //Cannot use func as a variable name at function scope
//since it is an argument even though
//this is within a different namespace
typedef union func{
int (*func)(int func); //Shows func() name and arg. names
//are different namespaces.
union u{
int func;
//...
}
} ;
}
int main(int main){
typedef struct main {
int main;
};
}
似乎 'main' 是文件级别的变量名和函数名的保留关键字,但不是 struct/tag 联合名。它在文件级别接受这个:
struct main {
int main;
//...
} not_main;
为什么名称space是原型的原因是没有意义的。如果没有一些实用性的话,就没有区别了。
初步
您正在混合几个适用于 C 标识符的不同概念:scope、namespace 和 linkage:
Scope 是程序文本区域,其中标识符和特定程序实体之间的给定关联是可见的并且可以使用。
Namespace 描述了这样一个事实,即 C 允许在相同的范围内使用相同的标识符来标识某些上下文可区分的类别中的 objects:标签、标签、结构和联合成员,以及其他一切。
Linkage是关于在一个翻译单元中声明的变量或函数是否可以从其他地方访问(外部链接),或者只能从同一翻译单元的其他地方访问翻译单元(内部链接),或仅在其定义范围内(无链接)。
范围和联系是完全不同的考虑因素。普通标识符的文件范围声明可以具有外部或内部链接。普通标识符的块范围声明可以有外部链接或没有链接。其他名称空间中的所有标识符声明都没有链接。
问题
...有点wide-ranging,但我会尽量抓住要点。
Besides error checking which only requires types, not identifiers,
what are some of the practical applications one might encounter for
leveraging function prototype scope? What are some of the advantages
to this?
拥有函数原型作用域使得在函数原型中包含参数名称成为可能。如果原型没有为函数参数标识符提供范围,那么它们可能属于的唯一范围就是文件范围,这意味着每个参数名称都必须与文件中的每个参数名称不同,并且从每个 file-scope 变量。这也意味着可以从函数外部访问函数参数。当然,提供不同参数名称的函数的多个声明会出现问题。真是一团糟!
的确,您不需要 不属于函数定义一部分的原型来提供参数名称——毕竟这是可选的。但是允许它对每个人来说都是一个很大的方便。好处包括
- 它可以更容易地创建单独的原型(只需从函数定义中取出一个并删除函数 body)
- 它使函数原型对人类读者来说更有意义,尤其是在参数名称选择得当的情况下
- 它允许编译器提供更有用的诊断消息
The definition of a function always includes the return argumen,
function name and function arguments including the type and names It
seem that having a prototype scope would be redundant since the
arguments are re-declared anyways with names
你好像在倒着看。函数原型范围的影响之一是在原型 中给出参数名称并不是 多余的。除了作为函数定义一部分的原型外,函数原型中标识符声明的范围是原型。它们不必将给定函数的一个原型匹配到另一个原型(尽管通常它们会这样做)。唯一对函数重要的参数名称 body 是与函数定义关联的参数名称。
但由于前面给出的原因,除其他外,我们通常希望 参数名称出现在函数原型中。尤其是出现在 headers 中的原型或以其他方式用于与包含函数定义的翻译单元不同的翻译单元。
The only value I can see is that it reserves the function name within
the file scope namespace meaning the function name could be used
within the prototype
它确实有这种效果,尽管我很少看到一个函数的标识符被用作它自己的参数之一的名称。但更常见的是 file-scope 函数名称也作为其他函数参数的名称出现。或者 file-scope 变量名作为函数参数的名称出现。
I had originally thought that the scope was independent of names
meaning file_scope_variable_name was different than
file_scope_function_name.
不,那是命名空间的问题。函数名和变量名属于同一个命名空间(普通标识符的命名空间),这是合适的,因为它们并不总是可以通过上下文相互区分。
[my compiler] will however allow main re-declared as a tag in the struct/union name space at any scope since they a block element like a function
是的,main
可以用作标记,尽管它也是具有外部链接的函数的标识符。并且还作为标签以及作为任意多个结构和联合的成员。 这是因为它们是独立的名称空间。与其试图学习命名空间如何建立的规则,不如只记住不同的命名空间——除了所有结构和联合的命名空间之外,它们可以作为一个类别,只有三个。
另外,main
可以作为函数原型中的参数名,也可以作为函数的局部变量,因为这样的标识符有不同的作用域.
并且 main
可以在任意多的不同翻译单元中用作单独 (file-scope) 函数的名称,只要 TU 不超过一个,并且 前提是整个程序中只有一个有外部联动.
首先:在搜索答案时,我可以[标记]要搜索的区域。这个发帖界面应该也支持吧
除了只需要类型而不需要标识符的错误检查之外,利用函数原型作用域可能会遇到哪些实际应用?这有什么好处?
function(int index, float array[index]);
//function prototype with names
对
function(int, float);
//function prototype(without identifiers)...
函数的定义总是包括 return 参数、函数名称和函数参数,包括类型和名称似乎具有原型作用域是多余的,因为参数无论如何都用名称重新声明:
原型: return_type return_name(argument_type, ...);
函数声明:
return_type return_name(argument_type argument_name, ...){
compound_statement_function_block;
}
我能看到的唯一价值是它在文件范围名称中保留了函数名称space,这意味着函数名称可以在原型中使用:
int func(int func); //Proto type declaration. Compiler allows this
//but throws warning about func() redeclaration
//but nothing about the arguments.
int function(int function){
int function;
}
我原以为作用域与名称无关,意思是 file_scope_variable_name 不同于 file_scope_function_name。它们在上下文和显着差异上足以成为这样,我认为这就是标准所要求的,但是我使用的编译器 gcc 不允许这样做。但是,它将允许在任何范围内将 main 重新声明为 struct/union 名称 space 中的标记,因为它们是像函数这样的块元素:
int func(int func){
typedef struct {
int func;
}; //Cannot use func as a variable name at function scope
//since it is an argument even though
//this is within a different namespace
typedef union func{
int (*func)(int func); //Shows func() name and arg. names
//are different namespaces.
union u{
int func;
//...
}
} ;
}
int main(int main){
typedef struct main {
int main;
};
}
似乎 'main' 是文件级别的变量名和函数名的保留关键字,但不是 struct/tag 联合名。它在文件级别接受这个:
struct main {
int main;
//...
} not_main;
为什么名称space是原型的原因是没有意义的。如果没有一些实用性的话,就没有区别了。
初步
您正在混合几个适用于 C 标识符的不同概念:scope、namespace 和 linkage:
Scope 是程序文本区域,其中标识符和特定程序实体之间的给定关联是可见的并且可以使用。
Namespace 描述了这样一个事实,即 C 允许在相同的范围内使用相同的标识符来标识某些上下文可区分的类别中的 objects:标签、标签、结构和联合成员,以及其他一切。
Linkage是关于在一个翻译单元中声明的变量或函数是否可以从其他地方访问(外部链接),或者只能从同一翻译单元的其他地方访问翻译单元(内部链接),或仅在其定义范围内(无链接)。
范围和联系是完全不同的考虑因素。普通标识符的文件范围声明可以具有外部或内部链接。普通标识符的块范围声明可以有外部链接或没有链接。其他名称空间中的所有标识符声明都没有链接。
问题
...有点wide-ranging,但我会尽量抓住要点。
Besides error checking which only requires types, not identifiers, what are some of the practical applications one might encounter for leveraging function prototype scope? What are some of the advantages to this?
拥有函数原型作用域使得在函数原型中包含参数名称成为可能。如果原型没有为函数参数标识符提供范围,那么它们可能属于的唯一范围就是文件范围,这意味着每个参数名称都必须与文件中的每个参数名称不同,并且从每个 file-scope 变量。这也意味着可以从函数外部访问函数参数。当然,提供不同参数名称的函数的多个声明会出现问题。真是一团糟!
的确,您不需要 不属于函数定义一部分的原型来提供参数名称——毕竟这是可选的。但是允许它对每个人来说都是一个很大的方便。好处包括
- 它可以更容易地创建单独的原型(只需从函数定义中取出一个并删除函数 body)
- 它使函数原型对人类读者来说更有意义,尤其是在参数名称选择得当的情况下
- 它允许编译器提供更有用的诊断消息
The definition of a function always includes the return argumen, function name and function arguments including the type and names It seem that having a prototype scope would be redundant since the arguments are re-declared anyways with names
你好像在倒着看。函数原型范围的影响之一是在原型 中给出参数名称并不是 多余的。除了作为函数定义一部分的原型外,函数原型中标识符声明的范围是原型。它们不必将给定函数的一个原型匹配到另一个原型(尽管通常它们会这样做)。唯一对函数重要的参数名称 body 是与函数定义关联的参数名称。
但由于前面给出的原因,除其他外,我们通常希望 参数名称出现在函数原型中。尤其是出现在 headers 中的原型或以其他方式用于与包含函数定义的翻译单元不同的翻译单元。
The only value I can see is that it reserves the function name within the file scope namespace meaning the function name could be used within the prototype
它确实有这种效果,尽管我很少看到一个函数的标识符被用作它自己的参数之一的名称。但更常见的是 file-scope 函数名称也作为其他函数参数的名称出现。或者 file-scope 变量名作为函数参数的名称出现。
I had originally thought that the scope was independent of names meaning file_scope_variable_name was different than file_scope_function_name.
不,那是命名空间的问题。函数名和变量名属于同一个命名空间(普通标识符的命名空间),这是合适的,因为它们并不总是可以通过上下文相互区分。
[my compiler] will however allow main re-declared as a tag in the struct/union name space at any scope since they a block element like a function
是的,main
可以用作标记,尽管它也是具有外部链接的函数的标识符。并且还作为标签以及作为任意多个结构和联合的成员。 这是因为它们是独立的名称空间。与其试图学习命名空间如何建立的规则,不如只记住不同的命名空间——除了所有结构和联合的命名空间之外,它们可以作为一个类别,只有三个。
另外,main
可以作为函数原型中的参数名,也可以作为函数的局部变量,因为这样的标识符有不同的作用域.
并且 main
可以在任意多的不同翻译单元中用作单独 (file-scope) 函数的名称,只要 TU 不超过一个,并且 前提是整个程序中只有一个有外部联动.