একটি অবৈধ পয়েন্টার উত্পাদন করে একটি ফাংশন রেফারেন্স কাস্টিং?


9

আমি তৃতীয় পক্ষের কোডে একটি ত্রুটি সন্ধান করছি এবং আমি এটিকে কিছু লাইনের সাথে সংকুচিত করেছি।

use libc::c_void;

pub unsafe fn foo() {}

fn main() {
    let ptr = &foo as *const _ as *const c_void;
    println!("{:x}", ptr as usize);
}

স্থিতিশীল 1.38.0 এ রান করুন এটি ফাংশন পয়েন্টারটি মুদ্রণ করে তবে বিটা (1.39.0-beta.6) এবং রাতের বেলা '1' দেয়। ( খেলার মাঠ )

কী _অনুমান করা হচ্ছে এবং কেন আচরণ পরিবর্তন হয়েছে?

আমি অনুমান করি এটি কাস্ট করার সঠিক উপায়টি কেবল সহজভাবে হবে foo as *const c_voidতবে এটি আমার কোড নয়।


আমি "কেন এটি পরিবর্তিত হয়েছে" এর উত্তর দিতে পারি না, তবে আমি আপনার সাথে সম্মত হই যে কোডটি শুরু করা ভুল। fooইতিমধ্যে একটি ফাংশন পয়েন্টার, তাই আপনার এটির কোনও ঠিকানা নেওয়া উচিত নয়। এটি দ্বিগুণ রেফারেন্স তৈরি করে, আপাতদৃষ্টিতে শূন্য আকারের ধরণের (এইভাবে যাদুটির মান 1)।
শেপমাস্টার

এটি আপনার প্রশ্নের সঠিক উত্তর দেয় না, তবে আপনি সম্ভবত এটি চান:let ptr = foo as *const fn() as *const c_void;
পিটার হল

উত্তর:


3

এই উত্তরটি এই প্রশ্নের দ্বারা অনুপ্রাণিত বাগ রিপোর্টের উত্তরগুলির ভিত্তিতে তৈরি ।

মরিচ প্রতিটি ফাংশন এর পৃথক ফাংশন আইটেম টাইপ , যা প্রতিটি অন্যান্য ফাংশন ফাংশন আইটেম ধরণ থেকে পৃথক । এই কারণে, ফাংশন আইটেম ধরণের কোনও উদাহরণ কোনও তথ্য সংরক্ষণ করার দরকার নেই - এটি কোন ফাংশনটিকে নির্দেশ করে তা এর ধরণ থেকে পরিষ্কার। সুতরাং ভেরিয়েবল এক্স ইন

let x = foo;

আকার 0 এর একটি পরিবর্তনশীল।

ফাংশন আইটেমের প্রকারগুলি স্পষ্টতই যেখানে প্রয়োজন সেখানে পয়েন্টার ধরণের কাজ করতে বাধ্য করে । পরিবর্তনশীল

let x: fn() = foo;

স্বাক্ষর সহ যে কোনও ক্রিয়াকলাপের জেনেরিক পয়েন্টার fn(), এবং এটি যে ফাংশনটিতে এটি নির্দেশ করে সেটি একটি পয়েন্টার সঞ্চয় করতে হয়, সুতরাং এর আকারটি xপয়েন্টারের আকার হয়।

আপনি যদি কোনও ফাংশনের ঠিকানা গ্রহণ করেন &foo, আপনি আসলে শূন্য আকারের অস্থায়ী মানের ঠিকানা নিচ্ছেন। আগে এই কমিট rustরেপো , শূন্য আকারের temporaries স্ট্যাক বরাদ্দের তৈরি করতে ব্যবহার করা, এবং &fooযে বরাদ্দ করছে তার ঠিকানার সাথে ফিরে আসেন। এই প্রতিশ্রুতিবদ্ধ হওয়ার কারণে শূন্য-আকারের প্রকারগুলি আর বরাদ্দ তৈরি করে না এবং এর পরিবর্তে যাদু ঠিকানা 1 ব্যবহার করে This এটি মরিচের বিভিন্ন সংস্করণের মধ্যে পার্থক্য ব্যাখ্যা করে।


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

ঠিক আছে, আমি গিথুব ইস্যুতে নতুন প্রতিক্রিয়াগুলি পড়িনি। আমি সেই কোডটি দিয়ে সেগফ্ল্ট পেতে পারি তবে, কোডটি যদি সেগফ্ল্টের কারণ হতে পারে তবে আমি অনুমান করি যে নতুন আচরণটি ঠিক আছে।
পিটার হল

দুর্দান্ত উত্তর। @ পিটারহল আমি একই জিনিসটি ভাবছিলাম, এবং আমি এখনও এই বিষয়ে 100% নই, তবে কমপক্ষে অস্থায়ী এবং অন্যান্য স্ট্যাক ভেরিয়েবলগুলির জন্য, 0x1 এ সমস্ত শূন্য-আকারের মান স্থাপনে কোনও সমস্যা হওয়া উচিত নয় কারণ সংকলকটি কোনওরকম করে না স্ট্যাক লেআউট সম্পর্কে গ্যারান্টি দেয় এবং আপনি যাইহোক জিএসটিগুলিতে পয়েন্টারগুলির স্বতন্ত্রতার গ্যারান্টি দিতে পারবেন না। এই থেকে বলতে ভিন্ন একটি ঢালাই, *const i32কাছে *const c_voidআমার বোঝার, এখনও পয়েন্টার পরিচয় সংরক্ষণে নিশ্চিত করা হয়, যা।
ট্রেন্টক্লি

2

কী _অনুমান করা হচ্ছে এবং কেন আচরণ পরিবর্তন হয়েছে?

প্রতিবার আপনি যখন কাঁচা পয়েন্টার castালাই করেন তখন আপনি কেবলমাত্র এক টুকরো তথ্য পরিবর্তন করতে পারেন (রেফারেন্স বা কাঁচা পয়েন্টার; পরিবর্তনীয়তা; প্রকার)। অতএব, আপনি যদি এই কাস্টটি করেন:

let ptr = &foo as *const _

যেহেতু আপনি কোনও কাঁচা পয়েন্টারের রেফারেন্স থেকে পরিবর্তন করেছেন, তাই অনুমান করা টাইপটি _ অবশ্যই অপরিবর্তিত হওয়া উচিত এবং তাই fooএটির ধরণ যা ফাংশনের জন্য কিছু অদম্য টাইপ foo

এটি না করার পরিবর্তে আপনি সরাসরি কোনও ফাংশন পয়েন্টারে কাস্ট করতে পারেন যা মরিচা সিনট্যাক্সে প্রকাশযোগ্য:

let ptr = foo as *const fn() as *const c_void;

কেন এটি পরিবর্তিত হয়েছে, এটি বলা শক্ত। এটি রাতের বিল্ডে একটি বাগ হতে পারে। এটির প্রতিবেদন করা উপযুক্ত - এটি কোনও বাগ না হলেও, সম্ভবত কী ঘটছে সে সম্পর্কে আপনি সম্ভবত সংকলক দলের কাছ থেকে একটি ভাল ব্যাখ্যা পাবেন!



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