__PRETTY_FUNCTION__, __FUNCTION__, __func__ এর মধ্যে পার্থক্য কী?


221

মধ্যে পার্থক্য কি __PRETTY_FUNCTION__, __FUNCTION__, __func__, এবং যেখানে তারা নথিভুক্ত করা হয়? কোনটি ব্যবহার করব তা আমি কীভাবে সিদ্ধান্ত নেব?

উত্তর:


266

__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


বিজয়ী উত্তরটির মতো দেখতে কীসের জন্য আপনি সি 99 স্পেসিফিকেশনটির (আপনার উত্সটিতে একটি ভাসমান লিঙ্ক আছে) লিঙ্ক করতে পারেন?
ম্যাট যোগদানকারী

1
@ কিংবদন্তি 2 কে: না, এটি সি ++ 11 এ "একটি বাস্তবায়ন-সংজ্ঞায়িত স্ট্রিং"। স্পেসিফিকেশন থেকে এটি আসল ভাষা। §8.4.1 দেখুন [dcl.fct.def.general] / 8।
জেমস ম্যাকনেলিস

2
মনে রাখবেন যে সিসিসি এবং ভিসি উভয়ই সরবরাহ করার সময় __FUNCTION__তারা কিছুটা আলাদা কাজ করে। gcc এর সমতুল্য দেয় __func__। উপাচার্য অজানা, কিন্তু এখনও শোভিত, নামের সংস্করণ দেয়। "ফু" নামের একটি পদ্ধতির জন্য, জিসিসি আপনাকে দেবে "foo", ভিসি দেবে "my_namespace::my_class::foo"
অ্যাড্রিয়ান ম্যাকার্থি

1
কৌতূহলোদ্দীপকটি হ'ল আমি এমএসভিসি 2017 সিই ব্যবহার করছি এবং আমি টাইপ করার সময় __PRETTY_FUNCTION__এটি তালিকাগুলিতে উপলব্ধ হিসাবে উপস্থিত হয় এবং যখন আমি এটির উপরে আমার মাউস সরিয়ে ফেলি তখন এটি ফাংশনটির নাম সম্পর্কিত তথ্য প্রদর্শন করে তবে এটি সংকলন করতে ব্যর্থ হয়।
ফ্রান্সিস কিউলার

1
@ ফ্রেঞ্চিসকলারও আমি এতে অবাক হয়েছি! এটিতে আমার প্রশ্ন দেখুন stackoverflow.com/questions/48857887/…
অ্যাডাম Badura

108

মূল প্রশ্নের পুরোপুরি উত্তর না দেওয়া সত্ত্বেও, সম্ভবত এটি বেশিরভাগ লোকেরা এটি দেখতে চেয়েছিল 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**)

6
আমি জানি এটি একটি যথাযথ উত্তর নয় তবে সম্ভবত এটি যাঁরা গুগল করেছিলেন তারা সকলেই এটি দেখতে চেয়েছিল :) (যদি তারা নিজেরাই চেষ্টা করতে অলস হয়)
পেট্র

5
ভাল কল, এটি দেখতে সুন্দর।
ম্যাট জয়েনার


ঠিক আছে, তবে __func__যখন এটি অন্য ফাংশনটিতে এম্বেড করা থাকে তখন কাজ করে? বলি আমার ফাংশন 1 আছে এটি কোনও আর্গুমেন্ট নেয় না। ফাংশন 1 কল করে ফাংশন 2 যা অন্তর্ভুক্ত করে __func__, কোন ফাংশনটির নাম মুদ্রিত হবে, 1 বা 2?
মারকাসজে

@ মার্কাসজে কেন নিজে চেষ্টা করবেন না ... এটি __func__একটি ম্যাক্রো, আপনি বর্তমানে যে কোনও ফাংশনে যাচ্ছেন তা এটি অনুবাদ করবে you আপনি যদি এটিকে F1 এ রেখে F2 এ f1 তে কল করেন তবে আপনি সর্বদা এফ 1 পাবেন।
পেটর

41

__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 ++ ফাংশনের ভিতরে ফাংশনের নাম পাওয়ার কোনও উপায় আছে কি?


13

__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 এখনও "সি ++ স্ট্যান্ডার্ড নয়," এটি এখনও খসড়া আকারে রয়েছে।
জেমস ম্যাকনেলিস

2
@ জেমস ম্যাকনেলিস এটি এখন, তাই মন্তব্যগুলি পরিষ্কার করুন, গোলমালটি সরাতে
ডারামারাক

7

তাদের ক্ষেত্রে, যারা ভিসে এটি কীভাবে অবাক হয় 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__প্রত্যাশিত হিসাবে ট্রিগার অঘোষিত শনাক্তকারী ত্রুটি ব্যবহার করে ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.