在C ++中使用标准库函数名作为标识符是否有效?

时间:2015-11-22 15:00:10

标签: c++ identifier reserved-words variable-names

考虑以下计划:

#include <cstdio>
int main()
{
    int printf=9;
    std::printf("%d",printf);
}

使用内置函数名作为变量声明中的标识符是否可以?这个定义良好的程序?我的意思是上面的程序行为定义明确吗?我很想知道C ++标准是否允许使用标准函数名作为变量的标识符

5 个答案:

答案 0 :(得分:4)

是的,这是明确定义的行为。您正在创建一个名为printf的int,并且您的范围中当前没有任何名为printf的内容。在标准作用域中有一些名为printf的东西,可能在全局作用域中,但在本地作用域中定义的int printf自动优先。

答案 1 :(得分:4)

它格式正确,因为std::printf::printf可能也已由<cstdio>声明!)都声明在与整数相同的范围,因此在块的持续时间内自动优先。

  

[C++14: 3.3.1/1]: [..] 为了确定声明的范围,有时可以方便地引用声明的潜在范围。除非潜在范围包含另一个同名声明,否则声明的范围与其潜在范围相同。在这种情况下,内部(包含)声明性区域中声明的潜在范围被排除在外部(包含)声明性区域中的声明范围之外。

例如,you generally wouldn't be able to do this at namespace scope

它定义明确,因为标准库中的实体名称本身并不是保留名称:

  

[C++14: 2.11/3]:此外,一些标识符保留供C ++实现和标准库(17.6.4.3.2)使用,否则不得使用;无需诊断。

     

[C++14: 17.6.4.3.2/1]:某些名称和功能签名集始终保留给实现:

     
      
  • 包含双下划线_ _或以下划线后跟大写字母(2.12)开头的每个名称都保留给实现以供任何使用。
  •   
  • 以下划线开头的每个名称都保留给实现,以用作全局命名空间中的名称。
  •   

答案 2 :(得分:3)

技术上允许这样做。有一些名称在全局命名空间中保留,但在函数内部,您的变量名称无论如何都不会在函数外部显示,所以不是问题。

使用它是一个糟糕的主意。

请注意这种方法可能存在问题。例如:

#define NULL 0

int main()
{
     int NULL = 42;
     printf("%d", NULL);
}

是不允许的,因为NULL是宏,而不是范围标识符。

编辑:我想补充说printf不是&#34;内置函数&#34;。它是一个&#34; C标准库函数&#34;。 bultin函数类似__builtin_sin,编译器&#34;知道&#34;这样它就可以得到优化。请注意,内置函数通常使用&#34;保留名称&#34;,以避免始终与现有库和用户定义的名称发生冲突。

答案 3 :(得分:0)

相对于标准库中的标识符,C ++标准仅声明标识符的以下重构

  

3此外,一些标识符保留供C ++使用   实现和标准库(17.6.4.3.2),不得   否则;无需诊断。

和(17.6.4.3.2全球名称)

  

1始终保留某些名称和功能签名集   实施:

     

- 每个包含双下划线_ _的名称或以。开头的名称   下划线后跟一个大写字母(2.12)保留给   实施任何用途。

     

- 以下划线开头的每个名称都保留给   实现用作全局命名空间中的名称。

因此,您可以使用与标准函数名称一致的标识符。

另一方面,这可能会使读者感到困惑并导致歧义。 考虑到标准允许编译器将标准C函数名称放在全局名称空间中。

答案 4 :(得分:0)

这样做是可以的。因为您定义的变量int printf不属于std作为printfcstdio中定义的变量using namespace std; 。所以你的程序名称实际上没有冲突。

但是,如果您声明

std::

在您的计划之前,并且之后在您的计划中没有使用#include<cstdio> using namespace std; int main() { int printf = 42; printf("%d", printf); } ,如果您不小心,它会导致问题。通常,当存在名称冲突时,编译器将使用在最小范围内定义的名称。所以如果你有这样的程序:

error: ‘printf’ cannot be used as a function

编译器将返回

printf

这是因为在此程序中,int在函数范围内定义为int printf( const char* format, ... ),在全局范围内定义为函数int main()。由于函数范围小于全局范围,因此在函数printf中,int被解释为int而不是函数。 var s1 = Symbol.for("foo"); var s2 = Symbol.for("foo"); s1 === s2; // true 不可调用,因此是错误消息。