जवाबों:
__func__एक अव्यवस्थित रूप से घोषित पहचानकर्ता है जो किसी वर्ण सरणी चर में विस्तार करता है जिसमें फ़ंक्शन नाम होता है जब इसे किसी फ़ंक्शन के अंदर उपयोग किया जाता है। इसे C99 में C से जोड़ा गया था। से C99 §6.4.2.2 / 1:
पहचानकर्ता
__func__को अनुवादक द्वारा स्पष्ट रूप से घोषित किया जाता है जैसे, प्रत्येक फ़ंक्शन परिभाषा के उद्घाटन ब्रेस के तुरंत बाद, घोषणाstatic const char __func__[] = "function-name";दिखाई दिया, जहाँ फ़ंक्शन-नाम lexically-enclosing फ़ंक्शन का नाम है। यह नाम फ़ंक्शन का अनियंत्रित नाम है।
ध्यान दें कि यह एक मैक्रो नहीं है और प्रीप्रोसेसिंग के दौरान इसका कोई विशेष अर्थ नहीं है।
__func__C ++ 11 में C ++ में जोड़ा गया था, जहां इसे "एक कार्यान्वयन-डे string ned स्ट्रिंग" (C ++ 11 C8.4.1 [dcl.fct.def.general] / 8) के रूप में निर्दिष्ट किया गया है, जो कि काफी नहीं है C. में विनिर्देशन के रूप में उपयोगी ( __func__C ++ में जोड़ने का मूल प्रस्ताव N1642 था )।
__FUNCTION__एक पूर्व-मानक विस्तार है जो कुछ सी संकलक समर्थन करते हैं (जीसीसी और विज़ुअल सी ++ सहित); सामान्य तौर पर, आपको इसका उपयोग करना चाहिए __func__जहां यह समर्थित है और केवल उपयोग करें __FUNCTION__यदि आप एक कंपाइलर का उपयोग कर रहे हैं जो इसका समर्थन नहीं करता है (उदाहरण के लिए, दृश्य C ++, जो C99 का समर्थन नहीं करता है और अभी तक C ++ 0x के सभी का समर्थन नहीं करता है, नहीं करता है प्रदान __func__)।
__PRETTY_FUNCTION__एक gcc एक्सटेंशन है जो ज्यादातर उसी तरह है __FUNCTION__, सिवाय इसके कि C ++ फ़ंक्शन के लिए फ़ंक्शन के हस्ताक्षर सहित "सुंदर" नाम शामिल है। दृश्य C ++ में एक समान (लेकिन काफी समान नहीं) विस्तार है __FUNCSIG__,।
अमानक मैक्रो के लिए, आप अपने संकलक के दस्तावेज से परामर्श करना चाहेंगे। Visual C ++ एक्सटेंशन C ++ कंपाइलर के "पूर्वनिर्धारित मैक्रोज़" के MSDN प्रलेखन में शामिल हैं । Gcc डॉक्यूमेंटेशन एक्सटेंशन को gcc डॉक्यूमेंटेशन पेज "फंक्शन नेम्स इन स्ट्रिंग्स" में वर्णित किया गया है ।
__FUNCTION__, वे थोड़ा अलग काम करते हैं। gcc के बराबर देता है __func__। वीसी अघोषित देता है, लेकिन अभी भी सजी है, नाम का संस्करण। "फू" नामक विधि के लिए, जीसीसी आपको देगा "foo", वीसी देगा "my_namespace::my_class::foo"।
__PRETTY_FUNCTION__करता हूं तो यह उपलब्ध होने के रूप में सूची में दिखाई देता है और जब मैं अपने माउस को ऊपर ले जाता हूं, तो यह फ़ंक्शन नाम के बारे में जानकारी प्रदर्शित करता है, हालांकि यह संकलन करने में विफल रहता है।
मूल प्रश्न का पूरी तरह से उत्तर नहीं देने के बावजूद, यह शायद वही है जो अधिकांश लोग इसे देखना चाहते थे।
GCC के लिए:
petanb@debian:~$ cat test.cpp
#include <iostream>
int main(int argc, char **argv)
{
std::cout << __func__ << std::endl
<< __FUNCTION__ << std::endl
<< __PRETTY_FUNCTION__ << std::endl;
}
petanb@debian:~$ g++ test.cpp
petanb@debian:~$
petanb@debian:~$ ./a.out
main
main
int main(int, char**)
__func__यह किसी अन्य फ़ंक्शन में एम्बेडेड होने पर काम करता है? कहते हैं कि मेरे पास फ़ंक्शन 1 है, यह कोई तर्क नहीं लेता है। function1 कॉल function2 जिसमें शामिल है __func__, कौन सा फ़ंक्शन नाम मुद्रित किया जाएगा, 1 या 2?
__func__एक मैक्रो है, यह आपके वर्तमान में जो भी फ़ंक्शन है, उसका अनुवाद करेगा। यदि आप इसे f1 में डालते हैं और f2 में f1 कॉल करते हैं, तो आपको हमेशा f1 मिलेगा।
__PRETTY_FUNCTION__ C ++ फीचर्स को हैंडल करता है: क्लासेस, नेमस्पेस, टेम्प्लेट और ओवरलोड
main.cpp
#include <iostream>
namespace N {
class C {
public:
template <class T>
static void f(int i) {
(void)i;
std::cout << __func__ << std::endl
<< __FUNCTION__ << std::endl
<< __PRETTY_FUNCTION__ << std::endl;
}
template <class T>
static void f(double f) {
(void)f;
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
}
int main() {
N::C::f<char>(1);
N::C::f<void>(1.0);
}
संकलित करें और चलाएं:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
आउटपुट:
f
f
static void N::C::f(int) [with T = char]
static void N::C::f(double) [with T = void]
आप फ़ंक्शन के नामों के साथ स्टैक के निशान में भी दिलचस्पी ले सकते हैं: C या C ++ में प्रिंट कॉल स्टैक
उबंटू 19.04, जीसीसी 8.3.0 में परीक्षण किया गया।
सी ++ 20 std::source_location::function_name
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r5.pdf C ++ 20 में चला गया, इसलिए हमारे पास इसे करने का एक और तरीका है।
प्रलेखन कहता है:
constexpr const char * function_name () कांस्ट नोसेप्ट;
6 रिटर्न: यदि यह ऑब्जेक्ट किसी फ़ंक्शन के शरीर में स्थिति का प्रतिनिधित्व करता है, तो कार्यान्वयन-परिभाषित NTBS देता है जो फ़ंक्शन नाम के अनुरूप होना चाहिए। अन्यथा, एक खाली स्ट्रिंग लौटाता है।
जहाँ NTBS का अर्थ है "शून्य समाप्त बाइट स्ट्रिंग"।
जब समर्थन जीसीसी के लिए आता है, तो मैं इसे एक कोशिश देता हूं, जीसीसी 9.1.0 के साथ g++-9 -std=c++2aअभी भी इसका समर्थन नहीं करता है।
https://en.cppreference.com/w/cpp/utility/source_location दावा उपयोग इस तरह होंगे:
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int main() {
log("Hello world!");
}
संभावित उत्पादन:
info:main.cpp:16:main Hello world!
इसलिए ध्यान दें कि यह कॉलर जानकारी कैसे लौटाता है, और इसलिए लॉगिंग में उपयोग के लिए एकदम सही है, यह भी देखें: क्या सी ++ फ़ंक्शन के अंदर फ़ंक्शन नाम प्राप्त करने का एक तरीका है?
__func__धारा 8.4.1 में C ++ 0x मानक में प्रलेखित है। इस मामले में यह प्रपत्र का एक पूर्वनिर्धारित फ़ंक्शन स्थानीय चर है:
static const char __func__[] = "function-name ";
जहां "फ़ंक्शन नाम" कार्यान्वयन युक्ति है। इसका मतलब यह है कि जब भी आप किसी फ़ंक्शन को घोषित करते हैं, तो कंपाइलर आपके फ़ंक्शन में इस चर को जोड़ देगा। एक ही का सच है __FUNCTION__और __PRETTY_FUNCTION__। उनके बड़े होने के बावजूद, वे मैक्रोज़ नहीं हैं। हालांकि __func__C ++ 0x के लिए एक अतिरिक्त है
g++ -std=c++98 ....
अब भी कोड का उपयोग कर संकलन करेगा __func__ ।
__PRETTY_FUNCTION__और __FUNCTION__यहाँ प्रलेखित रहे हैं http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names । __FUNCTION__के लिए सिर्फ एक और नाम है __func__। C __PRETTY_FUNCTION__के समान __func__है, लेकिन C ++ में इसके साथ ही हस्ताक्षर भी शामिल हैं।
__func__C ++ 03 का हिस्सा नहीं है। इसे C ++ 0x में जोड़ा गया है, लेकिन C ++ 0x अभी तक "C ++ मानक" नहीं है, यह अभी भी ड्राफ्ट फॉर्म में है।
उन लोगों के लिए, जो आश्चर्य करते हैं कि यह कैसे वी.एस.
MSVC 2015 अपडेट 1, cl.exe संस्करण 19.00.24215.1:
#include <iostream>
template<typename X, typename Y>
struct A
{
template<typename Z>
static void f()
{
std::cout << "from A::f():" << std::endl
<< __FUNCTION__ << std::endl
<< __func__ << std::endl
<< __FUNCSIG__ << std::endl;
}
};
void main()
{
std::cout << "from main():" << std::endl
<< __FUNCTION__ << std::endl
<< __func__ << std::endl
<< __FUNCSIG__ << std::endl << std::endl;
A<int, float>::f<bool>();
}
उत्पादन:
मुख्य से (): मुख्य मुख्य int __cdecl main (शून्य) A :: f () से: एक <int, नाव> :: च च शून्य __cdecl A <int, float> :: f <bool> (शून्य)
__PRETTY_FUNCTION__ट्रिगर अघोषित पहचानकर्ता त्रुटि का उपयोग करना , जैसा कि अपेक्षित था।