কাজ করার জন্য কোনও পয়েন্টারকে নতুন-বরাদ্দ করা কি আইনী?


33

ফাংশনগুলিতে পয়েন্টারগুলি সরল ডাটা পয়েন্টার নয় কারণ সেগুলি শূন্য * পয়েন্টারে সংরক্ষণ করা যায় না। তবুও, মনে হচ্ছে যে আমি নীচের কোডের মতো গতিশীল মেমোরিতে (জিসিসি এবং বিড়ম্বনায়) কোনও ফাংশন-পয়েন্টারটির অনুলিপি সঞ্চয় করতে পারি। এই জাতীয় কোডটি কি সি ++ স্ট্যান্ডার্ড অনুসারে আইনী, বা সম্ভবত এটি কোনও ধরণের সংকলক এক্সটেনশান?

তদ্ব্যতীত, ফাংশন-পয়েন্টারের ফলস্বরূপ পয়েন্টারটি একটি সরল ডেটা পয়েন্টার হিসাবে আচরণ করে: আমি এটিকে শূন্য * করে সংরক্ষণ করতে পারি এবং স্ট্যাটিক_কাস্ট দ্বারা এটি শূন্য * থেকে পুনরুদ্ধার করতে পারি। এই আচরণটি কি স্ট্যান্ডার্ড দ্বারা গ্যারান্টিযুক্ত?

int main()
{
  extern void fcn();
  void (*fcnPtr)() = &fcn;
  void (**ptrToFcnPtr)() = nullptr;

  //Make the copy of fcnPtr on the heap:
  ptrToFcnPtr = new decltype(fcnPtr)(fcnPtr);
  //Call the pointed-to function : 
  (**ptrToFcnPtr)();

  //Save the pointer in void* :
  void *ptr = ptrToFcnPtr;
  //retrieve the original ptr: 
  auto myPtr = static_cast< void(**)() > (ptr) ; 
  //free memory:
  delete ptrToFcnPtr ;

}

2
দয়া করে কাঁচা ফ্যানসিটন পয়েন্টার ব্যবহার করবেন না। std::functionপরিবর্তে ব্যবহার করুন।
কিছু প্রোগ্রামার বন্ধু 12

আপনার newকাস্ট করার দরকার নেই void*void* ptr = &fcnPtr;ঠিক তেমন কাজ করে, যেহেতু fcnPtrএকটি বস্তু, কোনও ফাংশন নয়।
আখরোট

5
@ সোপামপ্রগ্রামমারডুড std::functionহ'ল একটি নির্বিচারে কলযোগ্য স্টোরের জন্য একটি টাইপ-মুছে ফেলা পাত্রে, ফাংশন পয়েন্টারগুলির পক্ষে সত্যিই প্রতিস্থাপন নয় ...
মাইকেল কেনজেল

7
(@ সোপোপ্রগ্রামমারডুড) দয়া করে অন্ধভাবে ব্যবহার করবেন না / সুপারিশ করবেন না std::function। এটি "পলিমারফিক" ফাংশনগুলি সংরক্ষণ করার ক্ষমতার জন্য দুর্দান্ত (যেমন সঠিক স্বাক্ষরযুক্ত কিছু, যদিও এটি কিছু ল্যাম্বডাসের মতো রাজ্যযুক্ত থাকে) তবে এটি ওভারহেড যোগ করে যা প্রয়োজন হয় না। একটি ফাংশনের পয়েন্টার হ'ল পিওডি। ক std::functionনা।
ম্যাথু

2
@ ম্যাথেজ ন্যায্য হওয়ার জন্য, অ্যাড্রিয়ান গতিশীলভাবে পয়েন্টারটি কাজ করার জন্য বরাদ্দ দেওয়ার বিষয়ে এবং টাইপ-ইরেজিংয়ের সাথে এটি নির্দেশ করার বিষয়ে জিজ্ঞাসা করছে void*, সুতরাং এই প্রশ্নের প্রসঙ্গে std::functionমনে হচ্ছে তারা ঠিক কী খুঁজছিল। আমি সম্মত হই না যে ফাংশন পয়েন্টারগুলিকে এসপিডি-র সাধারণ বরখাস্ততা নিরবচ্ছিন্ন।
এরেরিকা

উত্তর:


27

ফাংশন পয়েন্টারগুলি অবজেক্ট পয়েন্টার না হলেও "কিছু ধরণের পয়েন্টার ফাংশন" এখনও অবজেক্ট টাইপ [বেসিক.টাইপস] / 8 । সুতরাং, ফাংশন পয়েন্টারগুলি নিজেরাই অবজেক্টস, কেবল যে বিষয়টিকে তারা নির্দেশ করে তা নয়।

সুতরাং, আপনি নিশ্চিত যে একটি নতুন এক্সপ্রেশন মাধ্যমে ফাংশন পয়েন্টার ধরণের একটি অবজেক্ট তৈরি করতে পারেন ...


9

যেহেতু সেগুলি (ফাংশন পয়েন্টার) কোনও শূন্য * পয়েন্টারে সংরক্ষণ করা যায় না।

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

reinterpret_cast<void*>(&function);

কাজ করার জন্য কোনও পয়েন্টারকে নতুন-বরাদ্দ করা কি আইনী?

অবশ্যই। ফাংশন পয়েন্টার সহ সমস্ত পয়েন্টারগুলি হ'ল অবজেক্ট এবং সমস্ত বস্তুকে গতিশীলভাবে বরাদ্দ করা যেতে পারে।

তদ্ব্যতীত, ফাংশন-পয়েন্টারের ফলাফল পয়েন্টারটি সরল ডেটা পয়েন্টার হিসাবে আচরণ করে

ফাংশন পয়েন্টার একটি অবজেক্ট। একটি ফাংশন পয়েন্টার না শুধুমাত্র "হিসেবে আচরণ করবে" থেকে পয়েন্টার কিন্তু হয় একটি বস্তু করার জন্য একটি পয়েন্টার।

আমি এটিকে শূন্য * এ সঞ্চয় করতে পারি এবং স্থির_কাস্ট দ্বারা এটি শূন্য * থেকে পুনরুদ্ধার করতে পারি। এই আচরণটি কি স্ট্যান্ডার্ড দ্বারা গ্যারান্টিযুক্ত?

পয়েন্টারটিকে অকার্যকর এবং পয়েন্টারের মধ্যে অবজেক্টের মধ্যে রূপান্তর অনুমোদিত, হ্যাঁ। এবং রাউন্ড ট্রিপ রূপান্তরটি মূল পয়েন্টারটি উত্পাদনের গ্যারান্টিযুক্ত।


ধন্যবাদ। তবে তারপরে ফাংশন-পয়েন্টারটিকে অকার্যকর * (বা অন্য উপায়ে) এ রূপান্তর করতে আমার পুনরায় ব্যাখ্যা_কাস্ট ব্যবহার করা দরকার, তাই না?
অ্যাড্রিয়ান

1
@ অ্যাড্রিয়ান হ্যাঁ আমি একটি উদাহরণ যুক্ত করেছি।
এরেরিকা

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