_ FUNC _ identifier

Source: Internet
Author: User

_ FUNC _ is a predefined identifier in the c99 standard, which is a static const char [],
It is implicitly defined in every function using _ FUNC.

The following is an example in iso9899.
# Include <stdio. h>
Void myfunc (void)
{
Printf ("% s/n", _ FUNC __);
/*...*/
}

Output: myfunc

As far as I know, it seems that only GCC supports this identifier. Other compiler vendors either do not support this identifier or extend it to others. for example, in vc7, only _ function _ and _ pretty_function _ in GCC are available __.
1. However, what I'm interested in about this feature is what it can output in C ++?
2. Can it be used to initialize the list of Constructors?
3. Can it be used as the default parameter?
4. What is the purpose besides exception information or debug information?
5. Should we use standard or extended identifiers?

The first problem is better solved. Just write some test code.
Because of the environment, I can only use GCC 3.4.2 for testing, except for _ FUNC _ in GCC.
_ Function _ and _ pretty_function __. the former outputs only one function name like the result of the preceding example, while the latter lists the function information in detail.

The following is the output of the _ FUNC _ feature in C ++.
# Include <cstdio>
# Include <cstdlib>

# Define extern_2

# DEFINE _ INFO (n) puts (N)
# Ifdef Standard
# Define Info () _ INFO (_ FUNC __)
# Endif
# Ifdef extern_1
# Define Info () _ INFO (_ function __)
# Endif
# Ifdef extern_2
# Define Info () _ INFO (_ pretty_function __)
# Endif

Namespace _ private {
Class testbase {
Public:
Virtual ~ Testbase (){}
};

Class test: Public testbase {
Public:
Test () {Info ();}

Template <class T>
Test (t) {Info ();}

Test (INT,...) {Info ();}

~ Test () {Info ();}

Static void bar () {Info ();}

Template <class T>
Operator T () const {
Info ();
Return T ();
}

Friend _ stdcall void Foo (testbase & T) {Info ();};

Struct widget {};
};
}

Int main (){
Using namespace _ private;
Using namespace STD;
{
Test T1;
Test T2 (0, 'A', 'B ');
Test const T3 = test (0 .);
Test: bar ();
Foo (T1 );
Int I = T3;
Test: widget WG = T3;
}
System ("pause ");
Return 0;
}

The default output of _ pretty_function _ is:
_ PRIVATE: Test ()
_ PRIVATE: Test (INT ,...)
_ PRIVATE: Test (t) [with T = double]
Static void _ PRIVATE: Test: bar ()
Void _ PRIVATE: Foo (_ PRIVATE: testbase &)
_ PRIVATE: Test: operator T () const [with T = int]
_ PRIVATE: Test: operator T () const [with T = _ PRIVATE: Test: widget]
Virtual _ PRIVATE: Test ::~ Test ()
Virtual _ PRIVATE: Test ::~ Test ()
Virtual _ PRIVATE: Test ::~ Test ()
Press any key to continue...

The basic format in GCC is:
(Static or virtual) namespace: Class: function (const or volatile), and there is an additional description of the template, but unfortunately there is no description of the call specification.

The second question is, "Can it be used for the initialization list of Constructors? "
Why? It is only implicitly defined in the function body, namely:
Struct {
A (): pstr (STR) {// err
Static const char STR [] = "hello ";
}
Const char * pstr;
};
However, this is wrong. The STR in the initialization list will be considered as not declared yet. But I use _ FUNC __
But no error is reported.
Struct {
A (): pstr (_ FUNC _) {// OK
Static const char STR [] = "hello ";
}
Const char * pstr;
};

Well, it seems that it is prior to the function body. (I tried GCC only. I am not sure whether this behavior is correct yet.) because of this uncertainty, I thought about the third question: "Can it be used for default parameters? ".

A simple code test shows that this is not possible:
Void Foo (char const * pstr =__ func _); // err
Try again
Void Foo (char const * pstr =__ function _); // OK
The encoding is passed, but pstr = "". (It seems that this is the difference between _ FUNC _ and _ function)
It seems that it cannot be used as the default parameter.

Well, really? Is there a special case? So I thought about the local class:

Void Foo (){
_ FUNC __; // It must be explicitly used once before bar definition _ FUNC __

Struct {
Void bar (char const * pstr =__ func _) {// OK
Puts (pstr );
}
};

A;
A. Bar (); // outputs "foo" instead of "bar"
}

I did not expect a good example of the fourth question. I only thought of two examples:
(Base64 encoding table)
Char
Abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789 (int I ){
If (I = 62) return '+ ';
If (I = 63) return '/';
Return _ FUNC _ [I];
}

Char
(* Enbase64tab) (INT) = & abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789;

(Command interpretation example)
Class command {
Virtual void do_execute () = 0;
Public:
Static void execute (const char * script []) {
/*
Foreach (VEC)
If (script [I] = Vec. ITER)
* ITER. do_execute ();
*/
}
Protected:
Static cmdvec VEC;
};

Cmdvec command: VEC;

Class EDIT: Public command {
Virtual void do_execute (){}
Static edit;
Edit () {command: Vec. push_back (STD: make_pair (_ FUNC __, this ));}
};
Edit EDIT: Edit;

Class search: Public command {
Virtual void do_execute (){}
Static search;
Search () {command: Vec. push_back (STD: make_pair (_ FUNC __, this ));}
};
Search search: search;

That is to say, you can use it if the function in your application is closely related to its name.

The fifth question is, which one is better?
I checked the materials on the Internet and called _ function _ as a macro of _ FUNC. but I actually tried this on the GCC Preprocessor. well, I usually use _ FUNC __, because it is short. and it is specified in the standard.

My personal understanding of this new feature is basically like this. It should be noted that _ FUNC _ should not be used as the variable name on the compiler that does not support the new feature, even if you don't think any newline is used, you should pay attention to this.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.