is it valid to use standard library function name as identifier in C++?

牧云@^-^@ 提交于 2021-01-29 02:21:24

问题


Consider following program:

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

Is it fine to use built in function name as an identifier in variable declaration? Is this well defined program? I mean is behaviour of above program well defined? I am curious to know whether the C++ standard allows to use standard function names as identifiers of variables


回答1:


It's well-formed because neither std::printf nor ::printf (which may also have been declared by <cstdio>!) are declared in the same scope as your integer, which therefore takes automatic precedence for the duration of the block.

[C++14: 3.3.1/1]: [..] To determine the scope of a declaration, it is sometimes convenient to refer to the potential scope of a declaration. The scope of a declaration is the same as its potential scope unless the potential scope contains another declaration of the same name. In that case, the potential scope of the declaration in the inner (contained) declarative region is excluded from the scope of the declaration in the outer (containing) declarative region.

For example, you generally wouldn't be able to do this at namespace scope.

It's well-defined because the names of entities in the standard library are not inherently reserved names:

[C++14: 2.11/3]: In addition, some identifiers are reserved for use by C++ implementations and standard libraries (17.6.4.3.2) and shall not be used otherwise; no diagnostic is required.

[C++14: 17.6.4.3.2/1]: Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.



回答2:


Yes, this is well defined behavior. You are creating an int named printf, and there is nothing currently named printf in your scope. There is something named printf in the standard scope and possibly in the global scope, but the int printf defined in local scope automatically takes precedence.




回答3:


It is technically allowed to do this. There are names that are reserved in the global namespace, but inside a function, your variable name won't be visible outside the function anyway, so not a problem.

It is a terrible idea to use this.

And beware that there CAN BE problems with this approach. For example:

#define NULL 0

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

is not allowed, since NULL is a macro, and not a scoped identifier.

Edit: I would add that printf is not a "built in function". It is a "C standard library function". A bultin function is something like __builtin_sin, which the compiler "knows about" so that it can be optimised. Note that builtin functions typically use "reserved names", to avoid colliding with existing library and user-defined names at all times.




回答4:


Relative to the identifiers in the standard libraries then the C++ Standard states only the following restruction for identifiers

3 In addition, some identifiers are reserved for use by C++ implementations and standard libraries (17.6.4.3.2) and shall not be used otherwise; no diagnostic is required.

And (17.6.4.3.2 Global names)

1 Certain sets of names and function signatures are always reserved to the implementation:

— Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.

— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

So you may use identifiers that coincide with standard function names.

On the other hand this can confuse readers of the code and lead to ambiguity. Take into account that the Standard allows compilers to place standard C function names in the global namespace.




回答5:


It is OK to do so. Because the variable int printf you defined do not belong to the namespace std as printf, which is defined in cstdio. So there is actually no conflict in names of your program.

However, if you declare

using namespace std;

before your program, and no std:: used later in your program, then it'll cause problems if you're not careful. Generally, when there is name conflicts, compiler will use the name defined in smallest scope. So if you have program like:

#include<cstdio>
using namespace std;

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

The compiler will return

error: ‘printf’ cannot be used as a function

This is because in this program, printf is defined as a int in function scope, and as a function int printf( const char* format, ... ) in global scope. Since function scope is smaller than global scope, in function int main(), printf is intepreted as int rather than function. int is not callable, hence the error message.



来源:https://stackoverflow.com/questions/33856187/is-it-valid-to-use-standard-library-function-name-as-identifier-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!