মধ্যে পার্থক্য কি __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
, এবং যেখানে তারা নথিভুক্ত করা হয়? কোনটি ব্যবহার করব তা আমি কীভাবে সিদ্ধান্ত নেব?
মধ্যে পার্থক্য কি __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
, এবং যেখানে তারা নথিভুক্ত করা হয়? কোনটি ব্যবহার করব তা আমি কীভাবে সিদ্ধান্ত নেব?
উত্তর:
__func__
একটি স্পষ্টভাবে ঘোষিত শনাক্তকারী যা কোনও ফাংশনের অভ্যন্তরে যখন এটি ব্যবহৃত হয় তখন ফাংশনটির নাম ধারণ করে একটি অক্ষর অ্যারে ভেরিয়েবলে প্রসারিত হয়। এটি সি 99 এ সি যুক্ত করা হয়েছিল। থেকে C99 §6.4.2.2 / 1:
শনাক্তকারীকে
__func__
অনুবাদকের দ্বারা স্পষ্টভাবে ঘোষণা করা হয়, তত্ক্ষণাত প্রতিটি ফাংশন সংজ্ঞা, প্রজ্ঞাপনের প্রারম্ভিক বন্ধনী অনুসরণ করেstatic const char __func__[] = "function-name";
উপস্থিত হয়েছে, যেখানে ফাংশন-নাম লেক্সিক্যালি-এনক্লোজিং ফাংশনের নাম। এই নামটি ফাংশনের অলঙ্কৃত নাম।
মনে রাখবেন যে এটি কোনও ম্যাক্রো নয় এবং প্রিপ্রোসেসিংয়ের সময় এর কোনও বিশেষ অর্থ নেই।
__func__
সি ++ এ সি ++ 11-এ যুক্ত করা হয়েছিল, যেখানে এটি "একটি বাস্তবায়ন-ডি-নেড স্ট্রিং" (সি ++ 11 §8.4.1 [dcl.fct.def.general] / 8) হিসাবে চিহ্নিত করা হয়েছে, যা যথেষ্ট নয় সি এর স্পেসিফিকেশন হিসাবে দরকারী ( __func__
সি ++ যুক্ত করার মূল প্রস্তাবটি ছিল N1642 )।
__FUNCTION__
একটি প্রাক-স্ট্যান্ডার্ড এক্সটেনশন যা কিছু সি সংকলক সমর্থন করে (জিসিসি এবং ভিজ্যুয়াল সি ++ সহ); সাধারণভাবে, আপনি __func__
যেখানে এটি সমর্থিত সেখানে ব্যবহার করতে হবে এবং __FUNCTION__
আপনি যদি কেবল এমন কোনও সংকলক ব্যবহার করেন যা এটি সমর্থন করে না (উদাহরণস্বরূপ, ভিজ্যুয়াল সি ++, যা C99 সমর্থন করে না এবং এখনও সমস্ত সি ++ 0x সমর্থন করে না, ব্যবহার করে না প্রদান __func__
)।
__PRETTY_FUNCTION__
একটি জিসিসি এক্সটেনশান যা বেশিরভাগের মতোই __FUNCTION__
, সি ++ ফাংশন ব্যতীত এতে ফাংশনের স্বাক্ষর সহ ফাংশনের "সুন্দর" নাম রয়েছে। ভিজ্যুয়াল সি ++ এর সমান (তবে একরকম নয়) এক্সটেনশন রয়েছে __FUNCSIG__
।
নন-স্ট্যান্ডার্ড ম্যাক্রোগুলির জন্য, আপনি আপনার সংকলকের ডকুমেন্টেশনের সাথে পরামর্শ করতে চাইবেন। সি ++ কম্পাইলারের "পূর্বনির্ধারিত ম্যাক্রোস" এর এমএসডিএন ডকুমেন্টেশনে ভিজ্যুয়াল সি ++ এক্সটেনশনগুলি অন্তর্ভুক্ত করা হয়েছে । Gcc ডকুমেন্টেশন এক্সটেনশনগুলি gcc ডকুমেন্টেশন পৃষ্ঠাতে "স্ট্রিং হিসাবে ফাংশন নাম" in
__FUNCTION__
তারা কিছুটা আলাদা কাজ করে। gcc এর সমতুল্য দেয় __func__
। উপাচার্য অজানা, কিন্তু এখনও শোভিত, নামের সংস্করণ দেয়। "ফু" নামের একটি পদ্ধতির জন্য, জিসিসি আপনাকে দেবে "foo"
, ভিসি দেবে "my_namespace::my_class::foo"
।
__PRETTY_FUNCTION__
এটি তালিকাগুলিতে উপলব্ধ হিসাবে উপস্থিত হয় এবং যখন আমি এটির উপরে আমার মাউস সরিয়ে ফেলি তখন এটি ফাংশনটির নাম সম্পর্কিত তথ্য প্রদর্শন করে তবে এটি সংকলন করতে ব্যর্থ হয়।
মূল প্রশ্নের পুরোপুরি উত্তর না দেওয়া সত্ত্বেও, সম্ভবত এটি বেশিরভাগ লোকেরা এটি দেখতে চেয়েছিল oo
জিসিসির জন্য:
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 আছে এটি কোনও আর্গুমেন্ট নেয় না। ফাংশন 1 কল করে ফাংশন 2 যা অন্তর্ভুক্ত করে __func__
, কোন ফাংশনটির নাম মুদ্রিত হবে, 1 বা 2?
__func__
একটি ম্যাক্রো, আপনি বর্তমানে যে কোনও ফাংশনে যাচ্ছেন তা এটি অনুবাদ করবে you আপনি যদি এটিকে F1 এ রেখে F2 এ f1 তে কল করেন তবে আপনি সর্বদা এফ 1 পাবেন।
__PRETTY_FUNCTION__
সি ++ বৈশিষ্ট্যগুলি পরিচালনা করে: শ্রেণি, নেমস্পেস, টেম্পলেট এবং ওভারলোড
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]
আপনি ফাংশন নাম সহ স্ট্যাক ট্রেসগুলিতে আগ্রহী হতে পারেন: সি বা সি ++ এ প্রিন্ট কল স্ট্যাক
উবুন্টু 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 এ গেছে, সুতরাং আমাদের এটি করার আর একটি উপায় আছে।
নথি বলছে:
কনস্টেক্সপ্রস কনট চর * ফাংশন_নাম () কনটেক্স নোসেকসেপ্ট;
6 রিটার্নস: যদি এই অবজেক্টটি কোনও ফাংশনের শরীরে কোনও অবস্থান প্রতিনিধিত্ব করে তবে একটি বাস্তবায়ন-সংজ্ঞায়িত এনটিবিএস প্রদান করবে যা ফাংশনের নামের সাথে মিল রাখে। অন্যথায়, একটি খালি স্ট্রিং প্রদান করে।
যেখানে এনটিবিএস অর্থ "নাল টার্মিনেটেড বাইট স্ট্রিং"।
সমর্থনটি জিসিসি, জিসিসি 9.1.0 এ পৌঁছানোর g++-9 -std=c++2a
পরেও এটি ব্যবহার না করে চেষ্টা করব।
https://en.cppreferences.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!
সুতরাং এটি কীভাবে কলারের তথ্য ফেরত দেয় এবং লগিংয়ে ব্যবহারের জন্য নিখুঁত তা নোট করুন, আরও দেখুন: C ++ ফাংশনের ভিতরে ফাংশনের নাম পাওয়ার কোনও উপায় আছে কি?
__func__
বিভাগ 8.4.1 এ সি ++ 0x স্ট্যান্ডার্ডে নথিভুক্ত করা হয়েছে। এক্ষেত্রে এটি ফর্মের একটি পূর্বনির্ধারিত ফাংশন স্থানীয় পরিবর্তনশীল:
static const char __func__[] = "function-name ";
যেখানে "ফাংশন নাম" বাস্তবায়ন স্পেসিফিক। এর অর্থ হ'ল আপনি যখনই কোনও ফাংশন ঘোষণা করেন, সংকলকটি আপনার ফাংশনে অন্তর্ভুক্তভাবে এই পরিবর্তনকটি যুক্ত করবে। একই __FUNCTION__
এবং সত্য __PRETTY_FUNCTION__
। তাদের বড়হস্ত হওয়া সত্ত্বেও, তারা ম্যাক্রোস নয়। যদিও __func__
সি ++ 0x এর একটি সংযোজন
g++ -std=c++98 ....
এখনও কোড ব্যবহার করে সংকলন করবে __func__
।
__PRETTY_FUNCTION__
এবং __FUNCTION__
এখানে নথিভুক্ত করা হয়েছে http://gcc.gnu.org/onlinesocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names । __FUNCTION__
এর অন্য একটি নাম __func__
। সি __PRETTY_FUNCTION__
হিসাবে একই __func__
তবে সি ++ এ এতে স্বাক্ষর টাইপও রয়েছে।
__func__
সি ++ 03 এর অংশ নয়। এটি সি ++ 0x এ যুক্ত করা হয়েছে, তবে সি ++ 0x এখনও "সি ++ স্ট্যান্ডার্ড নয়," এটি এখনও খসড়া আকারে রয়েছে।
তাদের ক্ষেত্রে, যারা ভিসে এটি কীভাবে অবাক হয় wonder
এমএসভিসি 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 (বাতিল) এ :: চ () থেকে: একটি <কোন int, ভাসা> :: চ চ বাতিল
__PRETTY_FUNCTION__
প্রত্যাশিত হিসাবে ট্রিগার অঘোষিত শনাক্তকারী ত্রুটি ব্যবহার করে ।