সি স্ট্যান্ডার্ডের জন্য কনস্ট-নেসকে পুনরাবৃত্তি বিবেচনা করার কারণ কী?


9

সি 99 স্ট্যান্ডার্ড 6.5.16: 2 এ বলেছে:

একটি অ্যাসাইনমেন্ট অপারেটরের বাম অপরেন্ডের মতো একটি পরিবর্তনযোগ্য লভ্যালু থাকতে হবে।

এবং .3.৩.২.১:1 অনুচ্ছেদে:

একটি পরিবর্তনযোগ্য লভ্যালু এমন একটি মূল্য রয়েছে যা অ্যারের প্রকারের নয়, অসম্পূর্ণ প্রকারের নয়, একটি কনস্ট-কোয়ালিফাইড টাইপ নেই, এবং যদি এটি কাঠামো বা ইউনিয়ন হয় তবে তার কোনও সদস্য নেই (অন্তর্ভুক্ত, পুনরাবৃত্তভাবে, কোনও সদস্য সহ) বা কনস্ট-কোয়ালিটি টাইপ সহ সমস্ত সমন্বিত সমষ্টি বা ইউনিয়নগুলির উপাদান)।

এখন, আসুন const structএকটি constক্ষেত্রবিহীন বিবেচনা করুন।

typedef struct S_s {
    const int _a;
} S_t;

মান অনুসারে, নিম্নলিখিত কোডটি অপরিবর্তিত আচরণ (ইউবি):

S_t s1;
S_t s2 = { ._a = 2 };
s1 = s2;

এর সাথে অর্থগত সমস্যাটি হ'ল এনকোলেজিং সত্তা ( struct) সত্তার ঘোষিত ধরণের দ্বারা বিচার করে (কেবল পঠনযোগ্য S_t s1নয়) বিবেচনা করা উচিত, তবে স্ট্যান্ডার্ড (2 টি ধারা) দ্বারা এটি লেখার যোগ্য হিসাবে বিবেচিত হবে না শীর্ষে) constক্ষেত্রের কারণে _a। স্ট্যান্ডার্ড একটি প্রোগ্রামার কোডটি পড়ার জন্য এটি অস্পষ্ট করে তোলে যে এই নিয়োগটি আসলে একটি ইউবি, কারণ যে ডাব্লু / ও struct S_s ... S_tটাইপের সংজ্ঞাটি বলা অসম্ভব ।

তদুপরি, ক্ষেত্রটিতে কেবল পঠনযোগ্য অ্যাক্সেসটি কেবল যেকোন উপায়ে সিন্টেক্সিকভাবে প্রয়োগ করা হয়েছে। constঅ- const structএর কিছু ক্ষেত্র সত্যই কেবল পঠনযোগ্য স্টোরেজে রাখা যাবে না। তবে এই জাতীয় মানের শব্দটি কোডটির বাইরে রয়েছে যা ইচ্ছাকৃতভাবে constএই ক্ষেত্রগুলির অ্যাক্সেসর পদ্ধতিতে ক্ষেত্রগুলির যোগ্যতা দূরে সরিয়ে দেয় , যেমন ( সি এর কাঠামোর ক্ষেত্রগুলিকে যোগ্য করে তোলা ভাল ধারণা? ):

(*)

#include <stdlib.h>
#include <stdio.h>

typedef struct S_s {
    const int _a;
} S_t;

S_t *
create_S(void) {
    return calloc(sizeof(S_t), 1);
}

void
destroy_S(S_t *s) {
    free(s);
}

const int
get_S_a(const S_t *s) {
    return s->_a;
}

void
set_S_a(S_t *s, const int a) {
    int *a_p = (int *)&s->_a;
    *a_p = a;
}

int
main(void) {
    S_t s1;
    // s1._a = 5; // Error
    set_S_a(&s1, 5); // OK
    S_t *s2 = create_S();
    // s2->_a = 8; // Error
    set_S_a(s2, 8); // OK

    printf("s1.a == %d\n", get_S_a(&s1));
    printf("s2->a == %d\n", get_S_a(s2));

    destroy_S(s2);
}

সুতরাং, কোনও কারণে, structপুরোপুরি কেবল পঠনযোগ্য হওয়ার জন্য এটি এটিকে ঘোষণা করার পক্ষে যথেষ্টconst

const S_t s3;

তবে সামগ্রিকভাবে structকেবল অ-পঠনযোগ্য হওয়ার জন্য এটি ডাব্লু / ও ও ঘোষণা করার পক্ষে যথেষ্ট নয় const

আমার মনে হয় যা আরও ভাল হবে তা হ'ল:

  1. ক্ষেত্রগুলি constসহ অ- কাঠামো তৈরিতে সীমাবদ্ধ করা এবং constএ জাতীয় ক্ষেত্রে ডায়াগনস্টিক জারি করা। এটি পরিষ্কার করে দেবে যে structকেবলমাত্র পঠনযোগ্য ক্ষেত্রগুলি কেবল পঠনযোগ্য সেগুলি ।
  2. উপরের কোডটি * (*) স্ট্যান্ডার্ডের সাথে সঙ্গতিপূর্ণ করে তুলতে constনন- constস্ট্রাক্টের সাথে সম্পর্কিত কোনও ক্ষেত্রে লেখার ক্ষেত্রে আচরণের সংজ্ঞা দেওয়া ।

অন্যথায় আচরণটি সামঞ্জস্যপূর্ণ এবং বোঝা শক্ত নয়।

সুতরাং, সি স্ট্যান্ডার্ডটি কারণ constহিসাবে এটি পুনরাবৃত্তি হিসাবে বিবেচনা করার কারণ কি ?


সত্যি কথা বলতে কি, আমি সেখানে কোনও প্রশ্ন দেখছি না।
বার্ট ভ্যান ইনজেন শেহেনো

@ বার্টওয়ানআইগেনশেনা শরীরের শেষে বিষয়টিতে বর্ণিত প্রশ্ন যুক্ত করতে সম্পাদনা করেছিলেন
মাইকেল পানকভ

1
ডাউনটা কেন?
মাইকেল পানকভ

উত্তর:


4

সুতরাং, সি স্ট্যান্ডার্ডের কারণ হিসাবে কনস্ট-নেসকে পুনরাবৃত্তি বিবেচনা করার কারণ কী?

একমাত্র প্রকারের দৃষ্টিকোণ থেকে, এটি না করা অনুভূত হবে (অন্য কথায়: মারাত্মকভাবে ভাঙা এবং ইচ্ছাকৃতভাবে বিশ্বাসযোগ্য নয়)।

এবং এটি স্ট্রাক্টের "=" অর্থের কারণেই: এটি একটি পুনরাবৃত্তির কাজ। এটি অনুসরণ করে যে অবশেষে আপনার s1._a = <value>"টাইপিংয়ের নিয়মের ভিতরে" ঘটছে। যদি স্ট্যান্ডার্ডটি "নেস্টেড" constক্ষেত্রগুলির জন্য এটির অনুমতি দেয় তবে এটি তার ধরণের সিস্টেম সংজ্ঞাটিতে একটি স্পষ্ট বিপরীতে হিসাবে মারাত্মক অসঙ্গতি যুক্ত করে (এটি constবৈশিষ্ট্যটিও ফেলে দিতে পারে, কারণ এটি কেবল তার অত্যন্ত সংজ্ঞা দ্বারা অকেজো এবং অবিশ্বস্ত হয়ে পড়ে)।

আপনার সমাধান (1), যতদূর আমি এটি বুঝতে পেরেছি, অকারণে পুরো কাঠামোটিকে এর যে constকোনও একটি ক্ষেত্র হতে বাধ্য করতে বাধ্য করছে const। এই ভাবে, s1._b = bএকটি অ-const জন্য অবৈধ হবে ._bএকটি অ-const উপর ক্ষেত্র s1একটি ধারণকারী const a


আমরা হব. Cসবেমাত্র একটি সাউন্ড টাইপ সিস্টেম রয়েছে (বছরের পর বছর ধরে একে অপরের উপর চাপানো কোণার মামলার মতো) like একটি থেকে এছাড়া অন্যান্য উপায় নিয়োগ করা structহয় memcpy(s_dest, s_src, sizeof(S_t))। এবং আমি নিশ্চিত যে এটি বাস্তবায়িত প্রকৃত উপায়। এবং এই জাতীয় ক্ষেত্রে এমনকি বিদ্যমান "টাইপ সিস্টেম" আপনাকে এটি করতে নিষেধ করে না।
মাইকেল পানকভ

2
খুবই সত্য. আমি আশা করি যে আমি সি এর টাইপ সিস্টেমটি সুদৃ .়ভাবে বোঝাতে চাইনি, কেবল এটি ইচ্ছাকৃতভাবে একটি নির্দিষ্ট শব্দার্থিককে ইচ্ছাকৃতভাবে পরাভূত করেছে। অধিকন্তু, যদিও সি এর টাইপ সিস্টেমটি দৃ strongly়ভাবে প্রয়োগ করা হয়নি তবে এটি লঙ্ঘনের উপায়গুলি প্রায়শই সুস্পষ্ট (পয়েন্টার, অপ্রত্যক্ষ অ্যাক্সেস, ক্যাসেট) - যদিও এর প্রভাবগুলি প্রায়শই অন্তর্ভুক্ত এবং ট্র্যাক করা শক্ত। সুতরাং, তাদের লঙ্ঘন করার জন্য সুস্পষ্ট "বেড়া" থাকা তাদের সংজ্ঞাগুলির মধ্যে দ্বন্দ্ব থাকার চেয়ে আরও ভালভাবে অবহিত করে।
থিয়াগো সিলভা

2

কারণ হ'ল কেবল পঠনযোগ্য ক্ষেত্রগুলি কেবল পঠনযোগ্য। সেখানে কোনও বড় অবাক হওয়ার কিছু নেই।

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

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


আমি 90% নিশ্চিত অপ্টিমাইজারগুলি ধরে নিতে পারে না যে constক্ষেত্রগুলি লিখিত হয়নি, কারণ আপনি সর্বদা ব্যবহার করতে পারেন memsetবা memcpy, এবং এটি স্ট্যান্ডার্ডের সাথে সামঞ্জস্যপূর্ণও হবে। (1) একটি পতাকা দ্বারা সক্ষম হওয়া খুব স্বল্পতম, অতিরিক্ত সতর্কতা হিসাবে প্রয়োগ করা যেতে পারে। (2) 'র যুক্তিপূর্ণ যে, ভাল, ঠিক - কোন উপায় একটি উপাদান এর structঅ লিখনযোগ্য বিবেচনা করা যেতে পারে যখন সমগ্র গঠন হয় লিখনযোগ্য।
মাইকেল পানকভ

"পতাকা দ্বারা নির্ধারিত একটি alচ্ছিক ডায়াগনস্টিক" স্ট্যান্ডার্ডটির দাবি করার জন্য একটি অনন্য প্রয়োজন হবে। তদ্ব্যতীত, পতাকা নির্ধারণ করা এখনও বিদ্যমান কোডটি ভেঙে দেবে, ফলস্বরূপ বাস্তবে কেউ পতাকাটি নিয়ে বিরক্ত করবে না এবং এটি একটি মৃত পরিণতি হবে। (২) হিসাবে, .3.৩.২.১ অনুচ্ছেদটি ঠিক এর বিপরীতটি নির্দিষ্ট করে: যখনই কোনও উপাদান থাকে তখন পুরো কাঠামোটি লিখিত হয় না । তবে অন্যান্য উপাদানগুলি এখনও রচনামূলক হতে পারে। Cf. সি ++ যা operator=সদস্যদের ক্ষেত্রেও সংজ্ঞায়িত করে এবং তাই operator=যখন কোনও সদস্য হয় তখন কোনও সংজ্ঞা দেয় না const। সি এবং সি ++ এখনও এখানে সামঞ্জস্যপূর্ণ।
এমসাল্টার

@ কনস্ট্যানটিয়াস - আপনি যে সদস্যটির দৃness়তাটি ইচ্ছাকৃতভাবে ঘনিষ্ঠ করার জন্য কিছু করতে পারেন তা অপ্টিমাইজারের পক্ষে সেই দৃness়তাটিকে উপেক্ষা করার কোনও কারণ নয়। আপনি কোনও ফাংশনের অভ্যন্তরে দৃ function়তা ফেলে দিতে পারেন, আপনাকে স্টাফ পরিবর্তন করতে দেয়। কিন্তু কলিং প্রসঙ্গে অপ্টিমাইজারটিকে এখনও ধরে নেওয়ার অনুমতি রয়েছে you স্থিরতা প্রোগ্রামারটির জন্য দরকারী, তবে এটি কিছু ক্ষেত্রে অপ্টিমাইজারের জন্য godশ্বর-প্রেরণও।
মাইকেল কোহেন

তারপরে কেন একটি লিখনযোগ্য কাঠামোটির সাথে ওভাররাইট করার অনুমতি দেওয়া হচ্ছে memcpy? অন্যান্য কারণ হিসাবে - ঠিক আছে, এটি উত্তরাধিকার, তবে কেন এটি প্রথম স্থানে করা হয়েছিল?
মাইকেল পানকভ

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