সংকলক কেন অনুপস্থিত সেমিকোলনটির প্রতিবেদন করে না?


115

আমার এই সাধারণ প্রোগ্রামটি রয়েছে:

#include <stdio.h>

struct S
{
    int i;
};

void swap(struct S *a, struct S *b)
{
    struct S temp;
    temp = *a    /* Oops, missing a semicolon here... */
    *a = *b;
    *b = temp;
}

int main(void)
{
    struct S a = { 1 };
    struct S b = { 2 };

    swap(&a, &b);
}

যেমন আদর্শ আইডোন.কম এ দেখা গেছে এটি একটি ত্রুটি দেয়:

prog.c: In function 'swap':
prog.c:12:5: error: invalid operands to binary * (have 'struct S' and 'struct S *')
     *a = *b;
     ^

সংকলকটি অনুপস্থিত অর্ধপরিচয়টি সনাক্ত করে না কেন?


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


16
কি এই পোস্টে অনুপ্রাণিত?
আর সাহু

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

4
@ টাভিয়ানবার্নস: মূল প্রশ্নটি ত্রুটিটি চেয়েছিল। এই প্রশ্নটি জিজ্ঞাসা করছে যে সংকলকটি কেন (কমপক্ষে অপারেটিং সিস্টেমের কাছে) ত্রুটির অবস্থানটি ভুল ব্যাখ্যা করে বলে মনে হচ্ছে।
টনিক

80
চিন্তাভাবনা করুন: যদি কোনও সংকলক নিয়মিতভাবে অনুপস্থিত আধা-কোলন সনাক্ত করতে পারে তবে ভাষার শুরু করতে আধা-কলোনগুলির প্রয়োজন হবে না।
ইউরো মিশেলি

5
সংকলক কাজ ত্রুটি রিপোর্ট করা হয়। ত্রুটিটি ঠিক করার জন্য কী পরিবর্তন করতে হবে তা নির্ধারণ করা আপনার কাজ।
ডেভিড শোয়ার্জ

উত্তর:


213

সি একটি ফ্রি-ফর্মের ভাষা। এর অর্থ আপনি এটিকে অনেক উপায়ে ফর্ম্যাট করতে পারেন এবং এটি এখনও আইনী প্রোগ্রাম হবে।

যেমন একটি বিবৃতি

a = b * c;

যেমন লেখা যেতে পারে

a=b*c;

বা পছন্দ

a
=
b
*
c
;

তাই সংকলক যখন লাইনগুলি দেখুন

temp = *a
*a = *b;

এটি এর অর্থ মনে করে

temp = *a * a = *b;

এটি অবশ্যই একটি বৈধ এক্সপ্রেশন নয় এবং সংকলকটি অনুপস্থিত সেমিকোলনের পরিবর্তে অভিযোগ করবে। এটি বৈধ না হওয়ার কারণ হ'ল কারণ aএটি একটি কাঠামোর পয়েন্টার, সুতরাং *a * aএকটি কাঠামোর উদাহরণ ( *a) এর সাথে একটি কাঠামোর ( a) বিন্দু দিয়ে গুণ করার চেষ্টা করা হচ্ছে ।

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

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

এবং কখনও কখনও এটি আরও খারাপ হয়ে যায়: আপনি যদি দুটি (বা আরও) শিরোনাম ফাইল অন্তর্ভুক্ত করেন এবং প্রথমটিতে একটি অসম্পূর্ণ ঘোষণা থাকে তবে সম্ভবত বাক্য বাক্সটি দ্বিতীয় শিরোলেখ ফাইলটিতে নির্দেশিত হবে।


এর সাথে সম্পর্কিত হ'ল ফলো-আপ ত্রুটিগুলির ধারণা । কিছু ত্রুটি, সাধারণত সেমিকোলনগুলি হারিয়ে যাওয়ার কারণে একাধিক ত্রুটি হিসাবে রিপোর্ট করা হয় । এই কারণেই ত্রুটিগুলি ঠিক করার সময় উপরে থেকে শুরু করা গুরুত্বপূর্ণ, কারণ প্রথম ত্রুটিটি ঠিক করা একাধিক ত্রুটিগুলি অদৃশ্য হয়ে যেতে পারে।

অবশ্যই এটি একবারে একটি ত্রুটি ঠিক করতে এবং ঘন ঘন recompiles হতে পারে যা বড় প্রকল্পগুলির সাথে জটিল হতে পারে। এই ধরণের ফলো-আপ ত্রুটিগুলি সনাক্তকরণ এমন কিছু যা অভিজ্ঞতার সাথে আসে এবং কয়েকবার এগুলি দেখার পরে আসল ত্রুটিগুলি খুঁজে বের করা এবং পুনরায় কম্পাইল করার জন্য একাধিক ত্রুটি সমাধান করা সহজ।


16
সি ++ এ, অতিরিক্ত বোঝা থাকলে বৈধ এক্সপ্রেশন temp = *a * a = *b হতে পারে operator*। (যদিও প্রশ্নটিকে "সি" হিসাবে ট্যাগ করা হয়েছে))
dan04

13
@ ডান04: যদি কেউ আসলে তা করে ... নাহ!
কেভিন

2
(ক) প্রথম রিপোর্ট করা ত্রুটি দিয়ে শুরু হওয়া সম্পর্কে পরামর্শের জন্য +1; এবং (খ) ত্রুটিটি যেখান থেকে জানা গেছে সেখান থেকে পিছন ফিরে তাকাতে হবে। আপনি জানেন যে আপনি সত্যিকারের প্রোগ্রামার যখন আপনি স্বয়ংক্রিয়ভাবে কোনও ত্রুটির প্রতিবেদনের আগে লাইনে তাকান :-)
ট্রিপহাউন্ড

@ ট্রাইপহাউন্ড খুব সহজেই যখন খুব বেশি সংখ্যক ত্রুটি থাকে, বা পূর্বে সংকলিত লাইনগুলি ত্রুটি নিক্ষেপ করছে ...
টিন উইজার্ড

1
মেটা সম্পর্কিত ক্ষেত্রে সাধারণত, কেউ ইতিমধ্যে জিজ্ঞাসা করেছে - meta.stackoverflow.com/questions/266663/…
স্টোরি টেলার - আনস্ল্যান্ডার মনিকা

27

সংকলকটি অনুপস্থিত অর্ধপরিচয়টি সনাক্ত করে না কেন?

মনে রাখতে হবে তিনটি বিষয়।

  1. সি-তে লাইন শেষগুলি কেবল সাধারণ সাদা স্থান।
  2. *সিতে উভয় অমান্যকারী এবং বাইনারি অপারেটর হতে পারে। অ্যানারি অপারেটর হিসাবে এর অর্থ "ডেরেফারেন্স", বাইনারি অপারেটর হিসাবে এর অর্থ "গুণ করা"।
  3. অ্যানারি এবং বাইনারি অপারেটরগুলির মধ্যে পার্থক্য তারা যে প্রেক্ষাপটে দেখা হচ্ছে তা থেকে নির্ধারিত হয়।

এই দুটি সত্যের ফলাফল যখন আমরা পার্স করি।

 temp = *a    /* Oops, missing a semicolon here... */
 *a = *b;

প্রথম এবং শেষটি *অবিচ্ছিন্ন হিসাবে ব্যাখ্যা করা হয় তবে দ্বিতীয়টি *বাইনারি হিসাবে ব্যাখ্যা করা হয়। সিনট্যাক্সের দৃষ্টিকোণ থেকে এটি দেখতে ঠিক আছে।

সংশ্লেষকারী যখন অপারেটরগুলির প্রকারের প্রসঙ্গে অপারেটরদের ব্যাখ্যা করার চেষ্টা করে তখন কোনও ত্রুটি দেখা যায় an


4

উপরে কিছু ভাল উত্তর, তবে আমি বিস্তারিত করব।

temp = *a *a = *b;

এটি আসলে x = y = z;যেখানে উভয় xএবং yএর মূল্য নির্ধারিত হয়েছে তার একটি ক্ষেত্রে এটি z

আপনি যা বলছেন তা হচ্ছে the contents of address (a times a) become equal to the contents of b, as does temp

সংক্ষেপে, *a *a = <any integer value>একটি বৈধ বিবৃতি। পূর্বে উল্লিখিত হিসাবে, প্রথমটি *একটি পয়েন্টারকে dereferences, যখন দ্বিতীয়টি দুটি মানকে গুণ করে।


3
বিন্যাসটি অগ্রাধিকার নেয়, সুতরাং এটি (ঠিকানাগুলির বিষয়বস্তুগুলি) বার (একটিকে নির্দেশক)। আপনি বলতে পারেন, কারণ সংকলন ত্রুটিটি "বাইনারি * অবৈধ অপারেশনগুলি ('স্ট্রাক্ট এস' এবং 'স্ট্রাক্ট এস *' আছে)" যা দুটি ধরণের types
দাকান্দি

আমি সি 99 এর পূর্বে কোড দিচ্ছি, সুতরাং কোনও বিলের কথা নয় :-) তবে আপনি একটি ভাল পয়েন্টটি (+1) করতে পারেন, যদিও কার্যনির্বাহী
ক্রমটি

1
তবে এই ক্ষেত্রে, yএমনকি একটি পরিবর্তনশীল নয়, এটি প্রকাশ *a *a, এবং আপনি কোনও গুণটির ফলাফল বরাদ্দ করতে পারবেন না।
বার্মার

@ বার্মার আসলেই কিন্তু সংকলকটি এতদূর পায় না, এটি ইতিমধ্যে সিদ্ধান্ত নিয়েছে যে "বাইনারি *" এর অপারেশনগুলি অ্যাসাইনমেন্ট অপারেটরের দিকে নজর দেওয়ার আগেই অবৈধ।
প্লাগওয়াশ

3

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

int foo;
...
float foo;

int foo;নিজেই ঘোষণাটি পুরোপুরি ঠিক আছে। তেমনি ঘোষণা float foo;। কিছু সংকলক প্রথমে যে ঘোষণাটি প্রকাশ করেছিল সেখানে লাইন নম্বরটি রেকর্ড করতে পারে এবং প্রোগ্রামারকে এমন ঘটনা সনাক্ত করতে সহায়তা করে যাতে পূর্ববর্তী সংজ্ঞাটি আসলে ভুল। সংকলকরা লাইন নম্বরগুলিকেও এর মতো কোনও কিছুর সাথে যুক্ত রাখতে পারে do, যা সম্পর্কিত whileজায়গায় সঠিক জায়গায় উপস্থিত না হলে রিপোর্ট করা যেতে পারে । সমস্যাগুলির সম্ভাব্য অবস্থানটি তত্ক্ষণাত্ লাইনের পূর্ববর্তী যেখানে ত্রুটিটি আবিষ্কার হয়েছিল তার ক্ষেত্রে, তবে সাধারণত সংকলকগণ পজিশনের জন্য একটি অতিরিক্ত প্রতিবেদন যুক্ত করতে বিরত হন না।

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