সংকলন সময়ে নিশ্চিত করুন যে কোনও পদ্ধতিতে ঠিক এক জায়গায় ডাকা হয়েছিল


15

সংকলনের সময় এটি নিশ্চিত করা সম্ভব যে কোনও পদ্ধতিতে ঠিক এক জায়গায় ডাকা হয়েছিল কিনা তা নিয়ে আমি আগ্রহী।

মনে রাখবেন যে ফাংশনটিকে একাধিকবার বলা হয় (যেমন একটি লুপে) - তবে এটি দুটি পৃথক লুপে কল করা উচিত নয়।

এটি দুটি ভাগে বিভক্ত হতে পারে, আমি যে সমাধানগুলির যে কোনও অংশকে কভার করে তা সম্পর্কে আগ্রহী:
(ক) কমপক্ষে একটি জায়গায় কোনও পদ্ধতি বলা হয়েছে তা নিশ্চিত করুন a
একটি পদ্ধতি আহ্বান করা নিশ্চিত করা (খ) সর্বাধিক এক জায়গায় একটি পদ্ধতি আহ্বান করা নিশ্চিত করা

কোডের কাঠামোর উপরে আমার সম্পূর্ণ নিয়ন্ত্রণ রয়েছে এবং একই ধারণা অর্জনকারী বিভিন্ন বুদ্ধিমানদের আমরা স্বাগত জানাই।

// class.h

class MyClass {
  public:
    void my_method();
}

নিম্নলিখিতগুলি সংকলন করা উচিত নয় (কখনও বলা হয় না)

#include "class.h"

int main() {
  MyClass my_class;
}

নিম্নলিখিতগুলি সংকলন করা উচিত নয় (একাধিক স্থানে ডাকা হয়)

#include "class.h"

int main() {
  MyClass my_class;
  my_class.my_method();
  while(true) {
    my_class.my_method();
  }
}

নিম্নলিখিতগুলি সংকলন করা উচিত (ঠিক এক জায়গায় ডাকা):

#include "class.h"

int main() {
  MyClass my_class;
  while(true) {
    my_class.my_method();
  }
}

2
এটি একটি পদ্ধতি না। সেই এক জায়গায় কোডটি ইনলাইন রাখুন।
ব্যবহারকারী 207421

2
আমি মনে করি আপনি ল্যাম্বডা দিয়ে এটিও করতে পারেন (এটি একটি খালি ল্যাম্বদা হতে পারে) কারণ বন্ধ করার ধরণটি প্রতিটি ল্যাম্বদার জন্য স্বতন্ত্র। আবার এটি রানটাইম ত্রুটি হতে পারে তবে এটি যা আপনি চেয়েছিলেন তা নয়। আপনি যে সমস্যাটি সমাধান করার চেষ্টা করছেন সে সম্পর্কে যদি আপনি আরও বিশদ সরবরাহ করেন তবে আমরা সম্ভবত এর আশেপাশে কোনও উপায় খুঁজে পেতে পারি।
ইন্ডিয়ানা কর্নিক

2
এটি করতে আপনি অ-মানক __COUNTER__ম্যাক্রো ব্যবহার করতে পারেন । কিছু একটা static_assert(__COUNTER__ == 0); my_class.my_method();। তবে কাউন্টার প্রতিটি অনুবাদ ইউনিটে পুনরায় সেট করে যাতে আপনি কেবল এটি পরীক্ষা করে দেখতে পারেন যে ফাংশনটি অনুবাদ ইউনিট প্রতি একবার ডাকা হয় is
ইন্ডিয়ানা কর্নিক

4
কেন আপনি যে কাজ করতে চান? কোনও ফাংশনের পয়েন্টের অংশটি হ'ল এটি একাধিক জায়গা থেকে কল করা যেতে পারে।
চিপস্টার

4
আপনি কেন এটি করতে চান তা আপনার ব্যাখ্যা করা উচিত । আপনি যে সমাধানটির জন্য জিজ্ঞাসা করছেন তা আপনার আসল লক্ষ্যগুলি অর্জন করার পক্ষে সেরা নয়।
দশ

উত্তর:


6

নিম্ন প্রযুক্তির পদ্ধতি:

যেহেতু কোড কাঠামোর উপর আপনার নিয়ন্ত্রণ রয়েছে (যার মধ্যে বিল্ড সিস্টেম অন্তর্ভুক্ত রয়েছে, আমি ধরে নিই), সুতরাং এখানে একটি নিম্ন প্রযুক্তি সমাধান রয়েছে:

  • ফাংশন নাম যথেষ্ট অনন্য করতে
  • আপনার কোডে ফাংশন নামের জন্য গ্রেপ। আপনি এটি দু'বার আশা করছেন (ধরে নিলেন যে আপনি ঘোষণা এবং সংজ্ঞাটি সমষ্টিযুক্ত):
    • একবার হেডারে
    • একবার একক কল সাইটে

বিকল্পভাবে:

আপনি যদি সত্যই, সত্যই, সত্যিই এটি C ++ দিয়ে সমাধান করতে চান তবে আপনি চেষ্টা করতে পারেন

  • সংকলন ইউনিটের মধ্যে ব্যবহারের সংখ্যা বের করতে একটি সংকলন টাইম কাউন্টার ব্যবহার করুন
  • নিশ্চিত করুন যে শিরোনামটি একাধিক সংকলনের ইউনিটে অন্তর্ভুক্ত করা হলে ফাংশনটি ওডিআর লঙ্ঘন করবে।

যাইহোক, সংকলনের সময় কাউন্টারগুলি কালো যাদু (বলে আমি এবং আমি সত্যিই টিএমপি পছন্দ করি), এবং এই উদ্দেশ্যে ওডিআর লঙ্ঘন করা বাধ্যতামূলকভাবে ভুডুর মতো মনে হয় (কমপক্ষে আপনাকে কোনও পরীক্ষার ক্ষেত্রে লিঙ্ক দিতে ব্যর্থ হবে)।

কিন্তু গুরুতরভাবে:

এটি করবেন না। আপনি যাই করুন না কেন এটি একটি মোড়ক ফাংশন দ্বারা প্রায় কোনও প্রচেষ্টা দিয়ে বিকৃত করা যেতে পারে:

auto call_my_method(MyClass& o)
{
   return o.my_method();
}

MyClass::my_method()কেবল মোড়কে বলা হয়। অন্য প্রত্যেকে কেবল মোড়কটিকে কল করে যা সম্ভবত সংকলক দ্বারা অন্তর্ভুক্ত।

অন্যরা যেমন পরামর্শ দিয়েছে: আপনি যা করার চেষ্টা করছেন তা যদি আপনি ব্যাখ্যা করেন তবে এটি অনেক বেশি সহায়ক হতে পারে।


1

এখানে একটি মোটামুটি ধারণা যা কাজ করতে পারে (একটি মন্তব্যের জন্য খুব দীর্ঘ - তবে একটি ভাল এসও উত্তরের জন্য অসম্পূর্ণ)।

আপনি টেমপ্লেট ইনস্ট্যান্টেশনগুলি গণনা / পরীক্ষা করে এটি অর্জন করতে সক্ষম হতে পারেন।
টেমপ্লেটগুলি শুধুমাত্র ব্যবহারের পরে ইনস্ট্যান্ট হয়

একইভাবে, টেমপ্লেট পদ্ধতি / ফাংশন সংস্থাগুলি কখনও কল না করা থাকলে তারা পার্স করা বা সংকলিত বা সংযুক্ত (বৈধ সিনট্যাক্স নিশ্চিত করার বাইরে) নয়। এর অর্থ এই যে তাদের দেহের মধ্যে কোনও তাত্পর্য তৈরি করা হয়নি)।

আপনি এমন একটি টেম্পলেট তৈরি করতে সক্ষম হতে পারেন যা কিছু বিশ্বব্যাপী ইনস্ট্যান্টেশন গণনা এবং তার উপর স্থিতিশীল দৃ .়তা রক্ষা করে (বা অতীতের তাত্ক্ষণিকতাগুলি পরীক্ষা করার জন্য অন্য কোনও টিএমপি পদ্ধতি)।


"গ্লোবাল" ইনস্ট্যান্টেশন গণনাটি বর্তমান সংকলন ইউনিটের স্থানীয় হবে।
পরমাণুসংস্থান

1

সি প্রিপ্রসেসর এবং জিএনইউ ইনলাইন সমাবেশটি ব্যবহার করে এই প্রশ্নের একটি আংশিক সমাধান রয়েছে:

শিরোনাম ফাইল a.h:

struct A {
    // Do not call this method directly, use the macro below to call it
    int _method_vUcaJB5NKSD3upQ(int i, int j);
};

// Use inline assembly to ensure that this macro is used at most once
#define method_vUcaJB5NKSD3upQ(args...) \
    _method_vUcaJB5NKSD3upQ(args); \
    asm (".global once_vUcaJB5NKSD3upQ; once_vUcaJB5NKSD3upQ:");

বাস্তবায়ন ফাইল a.cc:

#include <iostream>
#include "a.h"

int A::_method_vUcaJB5NKSD3upQ(int i, int j) { return i+j+5; }

// Ensure that the macro is used at least once
extern "C" const char once_vUcaJB5NKSD3upQ;
static const char get_vUcaJB5NKSD3upQ = once_vUcaJB5NKSD3upQ;

int main() {
    A a;
    for(int i=0; i<7; i++) {
        // Use a separate statement to call the method
        // (terminated by a semicolon, it cannot be a sub-expression)
        auto x = a.method_vUcaJB5NKSD3upQ(2, 3);
        std::cout << x << std::endl;
    }
    return 0;
}

এই সমাধানটি এই অর্থে আংশিক যে এটি মোড়ক ম্যাক্রো ব্যবহার না করে সরাসরি আন্ডারস্কোর দিয়ে পদ্ধতিটিকে কল করতে প্রোগ্রামটিকে বাধা দেয় না।


0

একটি কনস্টেক্সপ্র কাউন্টার ব্যবহার করুন। অন্য একটি প্রশ্নে একটি বাস্তবায়ন রয়েছে


1
মনে হচ্ছে এই পদ্ধতিটি দুর্গঠিত।
চিপস্টার

ইস্যুটি ওপেন- std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118 এই প্রশ্নের উত্তরে উল্লেখ করা হয়েছে যে এটি মানক একটি ত্রুটি এবং এটি গঠন করা উচিত।
SD57

সুতরাং এটি অসুস্থ না, অন্তত এখনও না?
চিপস্টার

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