সি ++ এ __FILE__, __LINE__, এবং __FUNCTION__ ব্যবহার


158

সাহসী যে আপনার সি ++ কম্পাইলার তাদের সমর্থন, সেখানে কোন বিশেষ কারণ নেই না ব্যবহার __FILE__, __LINE__এবং __FUNCTION__লগিং এবং ডিবাগিং উদ্দেশ্যে?

আমি প্রধানত ব্যবহারকারীকে বিভ্রান্তিমূলক তথ্য দেওয়ার সাথে উদ্বিগ্ন example উদাহরণস্বরূপ, অপ্টিমাইজেশনের ফলস্বরূপ ভুল লাইন নম্বর বা ফাংশনটি রিপোর্ট করা — বা ফলস্বরূপ একটি কার্যকারিতা হিট নিতে।

মূলত, আমি বিশ্বাস করতে পারেন __FILE__, __LINE__এবং __FUNCTION__থেকে সবসময় ডান জিনিস কি?


লাইন সঠিক জিনিস করা উচিত। আমি এটি এবং এর সংস্থাগুলি PRETTY_FUNCTION সহ ব্যাপকভাবে ব্যবহার করেছি । ... তবে ... ভাল, আমি এখনই কোডটি খুঁজছি যেখানে লাইন রয়েছে। সম্ভবত এটি চেষ্টা / ধরা ব্যতিক্রম হ্যান্ডলিংয়ের জন্য ক্যাচ ব্লকে রয়েছে বলে সম্ভবত।
ক্রেজি গ্লিউ

উত্তর:


191

__FUNCTION__অ মান হল __func__C99 / সি ++ 11 বিদ্যমান। অন্যরা ( __LINE__এবং __FILE__) ঠিক আছে।

এটি সর্বদা সঠিক ফাইল এবং লাইনটি রিপোর্ট করবে (এবং যদি আপনি __FUNCTION__/ ব্যবহার করতে পছন্দ করেন তবে কাজ করে __func__)। অপ্টিমাইজেশন হ'ল একটি অ-উপাদান, কারণ এটি একটি সংকলন সময় ম্যাক্রো সম্প্রসারণ; এটি কোনওভাবেই কার্য সম্পাদনকে প্রভাবিত করবে না


3
__func__সি ++ এ এক ধরণের সমস্যা। C99 ডিফল্ট আর্গুমেন্ট সম্পর্কে আরও একটি শব্দ বলে না এবং এরকম কিছু ক্ষেত্রে, যেখানে __func__সি ++ এ আচরণ করা উচিত তা এতটা স্পষ্ট নয় ।
উইলহেমটেল

4
@ তম: আপনি একটি ভাল পয়েন্ট করার সময়। আমি বেশ পরিষ্কার ছিলাম যে __func__সি 99+ এ বিদ্যমান, সি ++ তে নেই। নির্বিশেষে, আমি মনে করি __func__সি ++ এ একটি যুক্তিসঙ্গত বাস্তবায়ন কেবল মঙ্গলের নামে তৈরি হবে। যেহেতু আমি সংকলক লেখক নই, এটি আসলে আমার কল নয়।
ইভান তেরান

কোন সংকলকরা মোটেই সমর্থন __FUNCTION__করে না? সাম্প্রতিক জিসিসি ব্যতীত কোন সংকলকরা এটি একটি ম্যাক্রো নয়, একটি ভেরিয়েবল হিসাবে বিবেচনা করে?
বেসিন

36
__func__সি ++ 11 স্ট্যান্ডার্ডে এখন।
ভিএক্স

38

বিরল ক্ষেত্রে, __LINE__অন্য কোনও কিছুর দ্বারা দেওয়া লাইনটি পরিবর্তন করা কার্যকর হতে পারে । আমি দেখেছি জিএনইউ কনফিগার করে যে কিছু টেস্টের জন্য উপযুক্ত লাইন নম্বরগুলি রিপোর্ট করার পরে এটি মূল উত্স ফাইলগুলিতে প্রদর্শিত না হয় এমন লাইনগুলির মধ্যে কিছু ভুডু .োকানোর পরে। উদাহরণ স্বরূপ:

#line 100

নিম্নলিখিত লাইনগুলি __LINE__100 দিয়ে শুরু করবে You আপনি বিকল্পভাবে একটি নতুন ফাইল-নাম যুক্ত করতে পারেন

#line 100 "file.c"

এটি কেবল কদাচিৎ কার্যকর। তবে যদি এটির প্রয়োজন হয় তবে আমি জানি এমন কোনও বিকল্প নেই। প্রকৃতপক্ষে, লাইনটির পরিবর্তে, একটি ম্যাক্রোও খুব বেশি ব্যবহার করা যেতে পারে যার ফলস্বরূপ উপরের দুটি ফর্মের কোনওটিরই ফলস্বরূপ। বুস্ট প্রিপ্রোসেসর লাইব্রেরি ব্যবহার করে আপনি বর্তমান লাইনটি 50 দ্বারা বৃদ্ধি করতে পারবেন:

#line BOOST_PP_ADD(__LINE__, 50)

আমি ভেবেছিলাম এটা যেহেতু আপনি ব্যবহার সম্পর্কে জিজ্ঞাসা এটা উল্লেখ কারো উপকারে লাগতেছে __LINE__এবং __FILE__। সি ++ এর বাইরে কেউ কখনই যথেষ্ট চমক পায় না :)

সম্পাদনা: @ জোনাথন লেফলার মন্তব্যগুলিতে আরও কিছু ভাল ব্যবহারের কেস সরবরাহ করেছেন:

# লাইনের সাথে মেসিং প্রি-প্রসেসরগুলির জন্য খুব দরকারী যেগুলি ব্যবহারকারীর উত্স ফাইলের সাথে তাল মিলিয়ে ব্যবহারকারীর সি কোডে ত্রুটিগুলি বজায় রাখতে চায়। ইয়্যাক, লেক্স এবং (আমার কাছে আরও বাড়িতে) ইএসকিউএল / সি প্রিপ্রসেসরগুলি তা করে।


29

এফওয়াইআই: জি ++ মানহীন __PRETTY_FUNCTION__ ম্যাক্রো সরবরাহ করে। এখনও অবধি আমি C99 __func__ (ধন্যবাদ ইভান!) সম্পর্কে জানতাম না। আমি মনে করি যে আমি এখনও অতিরিক্ত শ্রেণীর স্কোপিংয়ের জন্য উপস্থিত থাকলে __PRETTY_FUNCTION__ পছন্দ করি।

পুনশ্চ:

static string  getScopedClassMethod( string thePrettyFunction )
{
  size_t index = thePrettyFunction . find( "(" );
  if ( index == string::npos )
    return thePrettyFunction;  /* Degenerate case */

  thePrettyFunction . erase( index );

  index = thePrettyFunction . rfind( " " );
  if ( index == string::npos )
    return thePrettyFunction;  /* Degenerate case */

  thePrettyFunction . erase( 0, index + 1 );

  return thePrettyFunction;   /* The scoped class name. */
}

2
__PRETTY_FUNCTION__ সম্পর্কে জেনে ভাল লাগছে। খুব দরকারী!
ঝেং কো

8

ব্যক্তিগতভাবে, আমি এইগুলি ডিবাগিং বার্তাগুলি ছাড়া অন্য কোনও কিছুর জন্য ব্যবহার করতে নারাজ। আমি এটি করেছি, তবে আমি গ্রাহকদের বা শেষ ব্যবহারকারীদের কাছে এই জাতীয় তথ্য না দেখানোর চেষ্টা করি। আমার গ্রাহকরা প্রকৌশলী নন এবং কখনও কখনও কম্পিউটার বুদ্ধিমান হন না। আমি এই তথ্যটি কনসোলে লগ করতে পারি, তবে আমি যেমন বলেছিলাম, অনিচ্ছাকৃতভাবে ডিবাগ বিল্ড বা অভ্যন্তরীণ সরঞ্জামগুলি বাদ দিয়ে। আমি মনে করি এটি আপনার কাছে থাকা গ্রাহক বেসের উপর নির্ভর করে।


29
"আমি এই তথ্যটি কনসোলে লগ করতে পারি" - বা আরও ভাল: কোনও ফাইলে লগইন করুন যাতে কোনও ভুল হয়ে থাকলে আপনি গ্রাহককে এটি আপনার কাছে প্রেরণ করতে বলতে পারেন ...
ক্রিস্টোফ

7

সি ++ 20 std::source_location

সি ++ অবশেষে একটি নন-ম্যাক্রো বিকল্প যুক্ত করেছে এবং ভবিষ্যতে সি ++ 20 ব্যাপক আকার ধারণ করার পরে এটি সম্ভবত প্রভাব ফেলবে:

নথি বলছে:

কনস্টেক্সপ্রস কনট চর * ফাংশন_নাম () কনটেক্স নোসেকসেপ্ট;

6 রিটার্নস: যদি এই অবজেক্টটি কোনও ফাংশনের শরীরে কোনও অবস্থান প্রতিনিধিত্ব করে তবে একটি বাস্তবায়ন-সংজ্ঞায়িত এনটিবিএস প্রদান করবে যা ফাংশনের নামের সাথে মিল রাখতে হবে should অন্যথায়, একটি খালি স্ট্রিং প্রদান করে।

যেখানে এনটিবিএস অর্থ "নাল টার্মিনেটেড বাইট স্ট্রিং"।

সমর্থনটি জিসিসি, জিসিসি 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!

__PRETTY_FUNCTION__বনাম __FUNCTION__বনাম __func__বনামstd::source_location::function_name

: এ উত্তর __PRETTY_FUNCTION__, __FUNCTION__, __func__ মধ্যে পার্থক্য কি?


1
নেই <experimental/source_location>বর্তমান জিসিসি -9 হবে।
陈浩南

5

আমি সব সময় তাদের ব্যবহার। লগ ফাইলগুলিতে আইপি দেওয়ার বিষয়টি কেবলমাত্র আমিই উদ্বিগ্ন। যদি আপনার ফাংশনটির নামগুলি সত্যিই ভাল হয় তবে আপনি সম্ভবত একটি ব্যবসায়িক গোপনীয়তা উদ্ঘাটন করা সহজ করতে পারেন। এটি ধরণের ডিবাগ প্রতীক সহ শিপিংয়ের মতো, জিনিসগুলি খুঁজে পাওয়া আরও বেশি কঠিন। 99.999% ক্ষেত্রে খারাপ কিছুই আসবে না।


1
আনতে ভাল পয়েন্ট। stringsএক্সিকিউটেবল থেকে সমস্ত স্ট্রিং-জাতীয় ডেটা বের করতে ইউটিলিটিটি ব্যবহার করে এই তথ্যটি বের করা তুচ্ছ । এমনকি সংকুচিত এক্সিকিউটেবলগুলিও বের করা যেতে পারে। আপনি গ্রাহক সাইটে যা পাঠিয়েছেন তা সম্পর্কে খুব সচেতন হন। প্রায়শই প্রতিযোগিরা আপনার এক্সিকিউটেবলের উপর হাত পেতে সক্ষম হন, যদিও তাদের এটি করার কথা নয়।
মার্টি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.