সি এবং সি ++ উভয় ক্ষেত্রেই বৈধ যে কোডগুলি প্রতিটি ভাষায় সংকলন করার সময় বিভিন্ন আচরণ তৈরি করতে পারে?


664

সি এবং সি ++ এর অনেক পার্থক্য রয়েছে এবং সমস্ত বৈধ সি কোড বৈধ সি ++ কোড নয়।
("বৈধ" দ্বারা আমি সংজ্ঞায়িত আচরণের সাথে স্ট্যান্ডার্ড কোড বোঝায়, অর্থাত্ বাস্তবায়ন-নির্দিষ্ট / অপরিজ্ঞাত / ইত্যাদি নয়)

কোন দৃশ্যকল্প যা উভয় সি এবং সি ++ মধ্যে বৈধ কোড এক টুকরা উত্পাদন করবে কি বিভিন্ন আচরণ যখন প্রতিটি ভাষায় একটি প্রমিত কম্পাইলার দিয়ে কম্পাইল?

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

  • প্রিপ্রোসেসর সম্পর্কিত কিছুই নেই (যার অর্থ হ্যাক #ifdef __cplusplus, প্রাগমাস ইত্যাদি নেই)
  • বাস্তবায়ন-সংজ্ঞায়িত যেকোনো কিছুই উভয় ভাষায় সমান (যেমন সংখ্যা সীমা ইত্যাদি) limits
  • আমরা প্রতিটি স্ট্যান্ডার্ডের যুক্তিসঙ্গত সাম্প্রতিক সংস্করণগুলির তুলনা করছি (উদাহরণস্বরূপ, সি ++ 98 এবং সি 90 বা
    তারপরে ) যদি সংস্করণগুলি বিবেচনা করে তবে দয়া করে উল্লেখ করুন যে প্রতিটি সংস্করণ আলাদা আচরণ করে।

11
যাইহোক, এটি একটি উপভাষায় প্রোগ্রাম করা কার্যকর হতে পারে যা একই সাথে সি এবং সি ++ হয়। আমি এটি অতীতে করেছি এবং একটি বর্তমান প্রকল্প: টিএক্সআর ভাষা। মজার বিষয় হল লুয়া ভাষার বিকাশকারীরাও একই কাজ করেছিলেন এবং তারা এই উপভাষাকে "ক্লিন সি" বলে। আপনি সি ++ কম্পাইলারগুলি থেকে আরও ভাল কমপাইল টাইম চেকিং এবং সম্ভবত অতিরিক্ত দরকারী ডায়াগনস্টিকসের সুবিধা পান, তবুও সি বহনযোগ্যতা ধরে রাখুন।
কাজ

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

13
পুনরায় খোলার মতামত যেমন আমার মনে হয় এটির একটি "হ্যাঁ" দিয়ে উত্তর দেওয়া যেতে পারে যার পরে একটি উদাহরণ দেওয়া যেতে পারে (নীচে প্রমাণিত হিসাবে)। আমি মনে করি এটি গঠনমূলক যে লোকেরা এটি থেকে প্রাসঙ্গিক আচরণ শিখতে পারে।
আন্ডারস আবেল

6
@ অ্যান্ডারস এবেল নির্ভুল উত্তর, যা সমস্তই সঠিক, এটি নির্বিঘ্নে প্রমাণ করে যে এটি একটি তালিকা তৈরির প্রশ্ন হিসাবে রয়ে গেছে। কোনও তালিকা না পেয়ে আপনি এই প্রশ্নটি জিজ্ঞাসা করতে পারতেন।
dmckee --- প্রাক্তন-মডারেটর বিড়ালছানা

2
@ ডিএমকেকে এর মূল্য কী, তার জন্য আমি আপনার সাথে একমত তবে, সি ++ ট্যাগ লোকেরা ... আমরা কি বলব ... ফিস্টি
জর্জ স্টকার

উত্তর:


397

নিম্নলিখিতটি, সি এবং সি ++ এ বৈধ, সি এবং সি ++ এর বিভিন্ন মান হিসাবে (সম্ভবত সম্ভবত) ফলাফল হতে চলেছে i:

int i = sizeof('a');

দেখুন সি / সি ++ মধ্যে অক্ষর ( 'একটি') আকার পার্থক্য একটি ব্যাখ্যা জন্য।

এই নিবন্ধ থেকে অন্য এক :

#include <stdio.h>

int  sz = 80;

int main(void)
{
    struct sz { char c; };

    int val = sizeof(sz);      // sizeof(int) in C,
                               // sizeof(struct sz) in C++
    printf("%d\n", val);
    return 0;
}

8
নিশ্চয়ই এটির প্রত্যাশা ছিল না! আমি আরও কিছু নাটকীয় কিছু আশা করছিলাম তবে এটি এখনও কার্যকর, ধন্যবাদ। :) +1
ব্যবহারকারী541686

17
+1 দ্বিতীয় উদাহরণটি structস্ট্রাক্ট নামগুলির আগে সি ++ এর প্রয়োজন হয় না এর জন্য এটি একটি ভাল ।
শেঠ কার্নেগি

1
@ অ্যান্ড্রে আমি কিছুক্ষণ আগে একই কথা ভেবে দেখেছিলাম এবং এটি পরীক্ষা করেছি এবং এটি আমার প্রত্যাশার বিপরীতে জিডিসি ৪.7.১ এ কাজ করেছে। এটি কি জিসিসিতে বাগ আছে?
শেঠ কার্নেগি

3
@ শেঠ কার্নেগি: একটি অ-সঙ্গতিপূর্ণ প্রোগ্রাম কাজ করতে ব্যর্থ হওয়ার প্রয়োজন নেই, তবে এটির কাজ করার নিশ্চয়তাও নেই।
আন্দ্রে ভিহারভ

3
struct sz { int i[2];};অর্থ হবে ++ যে C ও C আছে মান আলাদা উত্পাদন করতে। (যেখানে আকারের (ডিগ্রি) == 1 সহ একটি ডিএসপি একই মান উত্পাদন করতে পারে)।
মার্টিন বোনার

464

এখানে একটি উদাহরণ যা সি এবং সি ++ এ ফাংশন কল এবং অবজেক্ট ডিক্লেয়ারেশনের মধ্যে পার্থক্যের সুবিধা গ্রহণ করে পাশাপাশি C90 অঘোষিত ফাংশনগুলি কল করার অনুমতি দেয়:

#include <stdio.h>

struct f { int x; };

int main() {
    f();
}

int f() {
    return printf("hello");
}

সি ++ এ এটি কিছুই মুদ্রণ করবে না কারণ একটি অস্থায়ী fতৈরি এবং ধ্বংস হয়, তবে সি 90 এ এটি মুদ্রণ করবে helloকারণ ঘোষণা না করে ফাংশনগুলি কল করা যেতে পারে।

আপনি যদি নামটি fদু'বার ব্যবহার করার বিষয়ে ভাবছিলেন , তবে সি এবং সি ++ মানগুলি এটি স্পষ্টভাবে মঞ্জুরি দেয় এবং আপনাকে কোনও অবজেক্ট তৈরি struct fকরতে চাইলে কাঠামোটি ছিন্ন করতে বলতে হবে বা structআপনি যদি ফাংশন চান তবে ছেড়ে দিন ।


7
কঠোরভাবে সি এর অধীনে কথা বলা এটি সংকলন করবে না, কারণ "ইনট এফ ()" এর ঘোষণা "ইন মেইন ()" এর সংজ্ঞা অনুসারে হয়েছে :)
সোগারটার

15
@ সোসর্ট, সত্যি? codepad.org/STSQlUhh C99 সংকলক আপনাকে একটি সতর্কতা দেবে, তবে তারা আপনাকে এটি সংকলন করতে দেবে।
jrajav

22
সি ফাংশনগুলিতে @ সোগারটারকে সুস্পষ্টভাবে ঘোষণার অনুমতি দেওয়া হয়।
অ্যালেক্স বি

11
@ অ্যালেক্সবি সি 99 এবং সি 11 এ নেই।

6
@jrajav এগুলি তখন C99 সংকলক নয়। একটি সি 99 সংকলক একটি সিনট্যাক্স ত্রুটি হিসাবে অঘোষিত শনাক্তকারী সনাক্ত করে। এমন একটি সংকলক যা এটি করে না তা হয় সি 98 সংকলক, বা প্রাক-মানক বা অন্য ধরণের নন-কনফরম্যান্ট সংকলক।

430

সি ++ বনাম সি 90 এর জন্য বিভিন্ন আচরণ পাওয়ার কমপক্ষে একটি উপায় রয়েছে যা বাস্তবায়ন সংজ্ঞায়িত হয় না। সি 90 এর একক-লাইনের মন্তব্য নেই। একটু যত্ন সহ, আমরা এটি ব্যবহার করতে পারি C90 এবং C ++ এ সম্পূর্ণ ভিন্ন ফলাফলের সাথে একটি অভিব্যক্তি তৈরি করতে।

int a = 10 //* comment */ 2 
        + 3;

সি ++ এ, //লাইনের শেষ থেকে শেষ পর্যন্ত সমস্ত কিছু একটি মন্তব্য, সুতরাং এটি এই হিসাবে কাজ করে:

int a = 10 + 3;

যেহেতু সি 90 এর একক লাইনের মন্তব্য নেই, কেবলমাত্র /* comment */একটি মন্তব্য। প্রথম /এবং 2দুটিই আরম্ভের উভয় অংশ, তাই এটি বেরিয়ে আসে:

int a = 10 / 2 + 3;

সুতরাং, একটি সঠিক সি ++ সংকলক 13 টি দেবে, তবে একটি কঠোরভাবে সঠিক সি 90 সংকলক 8. অবশ্যই, আমি স্রেফ এখানে স্বেচ্ছাচারিত সংখ্যাগুলি বেছে নিয়েছি - আপনি যথাযথ হিসাবে দেখতে অন্যান্য নম্বর ব্যবহার করতে পারেন।


34
ডাব্লুএইউএ এটি মনের মতো! সমস্ত সম্ভাব্য বিষয়গুলির মধ্যে আমি কখনও ভাবিনি যে আচরণের পরিবর্তন করতে মন্তব্যগুলি ব্যবহার করা যেতে পারে ha +1
ব্যবহারকারী541686

89
এমনকি এটি ছাড়া 2, এটি 10 / + 3বৈধ (অ্যানারি +) হিসাবে পড়বে ।
বেনোইট

12
মজাদার জন্য এখন এটি পরিবর্তন করুন যাতে সি এবং সি ++ উভয়ই পৃথক গাণিতিক এক্সপ্রেশন গণনা করে একই ফলাফলের জন্য মূল্যায়ন করে।
রায়ান সি থম্পসন

21
নিবন্ধন করুন s /
2/1

4
@ মেহরদাদ আমি কি ভুল বা মন্তব্য প্রিপ্রোসেসর সম্পর্কিত? আপনার প্রশ্নের উত্তর হিসাবে তাদের এইভাবে বাদ দেওয়া উচিত! ;-)
এলে

179

সি 90 বনাম সি ++ 11 ( intবনাম double):

#include <stdio.h>

int main()
{
  auto j = 1.5;
  printf("%d", (int)sizeof(j));
  return 0;
}

ইন সি এর autoঅর্থ স্থানীয় পরিবর্তনশীল। C90 এ ভেরিয়েবল বা ফাংশনের ধরণ বাদ দেওয়া ঠিক আছে। এটি ডিফল্ট int। সি ++ ১১ এর autoঅর্থ সম্পূর্ণ ভিন্ন কিছু, এটি সংকলকটিকে এটি আরম্ভ করার জন্য ব্যবহৃত মান থেকে ভেরিয়েবলের ধরণটি নির্ধারণ করতে বলে।


10
সি 90 আছে auto?
শেঠ কার্নেগি

22
@ শেঠ কার্নেগি: হ্যাঁ, এটি স্টোরেজ ক্লাস; আপনি এটি বাদ দিলে এটি ডিফল্টরূপে ঘটে তাই কোনও এটি ব্যবহার করেনি এবং তারা এর অর্থ পরিবর্তন করে। আমি মনে করি এটি intডিফল্টরূপে। এই চালাক! +1
ব্যবহারকারী541686

5
সি 11 এর অন্তর্নিহিত- নেই int
আর .. গীটহাব বন্ধ হেল্পিং আইসিসি

23
@ কিথথম্পসন আহ, আমি অনুমান করছি আপনারা অনুমানকে বোঝাচ্ছেন int। তবুও, সত্যিকারের বিশ্বে, যেখানে প্রচুর উত্তরাধিকারের কোড রয়েছে এবং মার্কেট লিডার এখনও সি 99 কার্যকর করেনি এবং এটি করার কোনও ইচ্ছা নেই, "সি এর একটি অপ্রচলিত সংস্করণ" কথা বলা অবাস্তব।
জিম বাল্টার

11
"প্রতিটি ভেরিয়েবলের একটি স্পষ্ট স্টোরেজ ক্লাস থাকা আবশ্যক truly আপনার সত্য, উচ্চতর পরিচালন।"
বেটাউন

120

আরেকটি উদাহরণ যা আমি এখনও উল্লেখ করি নি, এটি একটি প্রাক প্রসেসরের পার্থক্য তুলে ধরে:

#include <stdio.h>
int main()
{
#if true
    printf("true!\n");
#else
    printf("false!\n");
#endif
    return 0;
}

এটি সিতে "মিথ্যা" এবং সি ++ এ "সত্য" মুদ্রণ করে - সি-তে যে কোনও অপরিজ্ঞাত ম্যাক্রো 0 তে মূল্যায়ন করে C সি ++ তে, 1 টি ব্যতিক্রম রয়েছে: "সত্য" 1 টিতে মূল্যায়ন করে।


2
মজাদার. এই পরিবর্তনের পিছনে যুক্তি কি কেউ জানেন?

3
কারণ "সত্য" একটি মূল শব্দ / বৈধ মান, সুতরাং এটি কোনও "সত্য মানের" (যেমন কোনও ধনাত্মক পূর্ণসংখ্যার মতো) এর মতো সত্য হিসাবে মূল্যায়ন করা হয়। আপনি এখনও সি ++ তে "মিথ্যা" প্রিন্ট করতে সত্য মিথ্যা নির্ধারণ করতে পারেন;)
কফডি ডেভেলপার

22

2
@ ডারিওওউ কি ইউবিতে এই জাতীয় পুনঃনির্ধারণের ফলাফল দেবে না?
রুসলান

3
@ ডারিওও: হ্যাঁ, আপনি ভুল বলেছেন। কীওয়ার্ডগুলির পুনরায় সংজ্ঞা অনুমোদিত নয়, শাস্তি ভাগ্যের (ইউবি) এ ছেড়ে গেছে। প্রিপ্রোসেসর হ'ল সংকলনের একটি পৃথক পর্যায় comp
Deduplicator

108

প্রতি সি ++ 11 মান:

ক। কমা অপারেটর সিতে লভ্যালু-থেকে-রুল্যু রূপান্তর সম্পাদন করে তবে সি ++:

   char arr[100];
   int s = sizeof(0, arr);       // The comma operator is used.

সি ++ এ এই এক্সপ্রেশনটির মান 100 হবে এবং সি তে এটি হবে sizeof(char*)

খ। সি ++ তে গণনার প্রকারটি হ'ল তার এনাম। সি তে গণনার প্রকারটি অন্তর্নিহিত।

   enum E { a, b, c };
   sizeof(a) == sizeof(int);     // In C
   sizeof(a) == sizeof(E);       // In C++

এর অর্থ এটি sizeof(int)সমান নাও হতে পারে sizeof(E)

গ। সি ++ এ খালি প্যারাম তালিকা সহ ঘোষিত একটি ফাংশন কোনও আর্গুমেন্ট নেয় না। সিতে খালি প্যারাম তালিকার অর্থ ফাংশন প্যারামগুলির সংখ্যা এবং ধরণের অজানা।

   int f();           // int f(void) in C++
                      // int f(*unknown*) in C

প্রথমটিও অ্যালেক্সির মতো বাস্তবায়ন-সংজ্ঞায়িত। তবে +1।
শেঠ কার্নেগি

1
@ শেঠ, উপরের সমস্ত উপাদান সি ++ 11 স্ট্যান্ডার্ডের আনেক্সেক্স সি 1 থেকে সরাসরি নেওয়া হয়েছে।
কিরিল কোবেলেভ

হ্যাঁ তবে এটি এখনও বাস্তবায়ন-সংজ্ঞায়িত। sizeof(char*)100 হতে পারে যার ক্ষেত্রে প্রথম উদাহরণটি সি এবং সি ++-তে একই পর্যবেক্ষণযোগ্য আচরণ তৈরি করবে (উদাহরণস্বরূপ যদিও প্রাপ্তির পদ্ধতিটি sআলাদা হবে, sতবে এটি 100 এর সমাপ্ত হবে)। ওপি উল্লেখ করেছে যে এই ধরণের বাস্তবায়ন-সংজ্ঞায়িত আচরণটি ঠিক ছিল কারণ তিনি কেবল ভাষা-উকিলের উত্তরগুলি এড়াতে চেয়েছিলেন, সুতরাং প্রথমটি তার ব্যতিক্রম দ্বারা ভাল। তবে দ্বিতীয়টি যে কোনও ক্ষেত্রেই ভাল।
শেঠ কার্নেগি

5
একটি সহজ ফিক্স আছে - কেবল উদাহরণটি পরিবর্তন করুন:char arr[sizeof(char*)+1]; int s = sizeof(0, arr);
মানকারে

5
বাস্তবায়ন-সংজ্ঞায়িত পার্থক্য এড়ানোর জন্য, আপনার কাছে ব্যবহার করতে পারে void *arr[100]। এক্ষেত্রে কোনও উপাদান একই উপাদানটির পয়েন্টার হিসাবে একই আকার, সুতরাং যতক্ষণ না 2 বা ততোধিক উপাদান থাকে ততক্ষণ অ্যারে অবশ্যই তার প্রথম উপাদানটির ঠিকানার চেয়ে বড় হতে হবে।
ফিনউইউ

53

এই প্রোগ্রামটি 1সি ++ এবং সিতে মুদ্রণ করে 0:

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

int main(void)
{
    int d = (int)(abs(0.6) + 0.5);
    printf("%d", d);
    return 0;
}

এই ঘটনা না থাকায় double abs(double)C ++ জমিদার, তাই abs(0.6)আয় 0.6যখন সি এটা ফেরৎ 0আবাহন আগে অন্তর্নিহিত ডবল-টু-int- এ রূপান্তর কারণে int abs(int)। সি তে fabsআপনাকে কাজ করতে হবে double


5
এই সমস্যাটির সাথে অন্য কারও কোডটি ডিবাগ করতে হয়েছিল। ওহ কিভাবে আমি এটা পছন্দ। যাইহোক আপনার প্রোগ্রামটি 0++ তেও মুদ্রণ করছে। সি ++ এর শিরোনামটি "cmath" ব্যবহার করতে হবে তুলনা দেখুন প্রথম এক রিটার্ন 0 আদর্শ one.com/0tQB2G ২ য় এক ফিরে আসছেন 1 আদর্শ one.com/SLeANo
CoffeDeveloper

খুশী / দুঃখিত যে আমিই একমাত্র না যারা ডিবাগিংয়ের মাধ্যমে এই পার্থক্যটি খুঁজে পেয়েছি। সবেমাত্র VS2013 এ পরীক্ষা করা হয়েছে, এই বিষয়বস্তু সহ কেবল একটি ফাইল খালি এক্সটেনশন .cpp হলে 1 এবং এক্সটেনশন .c হলে 0 আউটপুট দেয়। দেখে মনে হচ্ছে <math.h> পরোক্ষভাবে ভিএস-এ অন্তর্ভুক্ত রয়েছে
পাভেল চিকুলাভ

এবং ভিএস সি ++ এর মতো দেখায়, <math.h> সি ++ স্টাফকে বিশ্বব্যাপী নেমস্পেসে অন্তর্ভুক্ত করে, যেখানে জিসিসির ক্ষেত্রে এটি নেই। নিশ্চিত নয় যা তবে এটি স্ট্যান্ডার্ড আচরণ।
পাভেল চিকুলাভ

2
এই নির্দিষ্ট কোড নমুনা বাস্তবায়ন নির্ভর: stdlib.hশুধুমাত্র সংজ্ঞায়িত abs(int)এবং abs(long); সংস্করণ abs(double)দ্বারা ঘোষণা করা হয় math.h। সুতরাং এই প্রোগ্রামটি এখনও abs(int)সংস্করণ কল করতে পারে । এটি একটি বাস্তবায়ন বিশদ যা অন্তর্ভুক্ত করার stdlib.hকারণও বোধ math.hকরে। (আমি মনে করি এটি abs(double)ডেকে আনা হলে এটি একটি বাগ হতে পারে , তবে অন্যান্য এস্পকে math.hঅন্তর্ভুক্ত করা হয়নি)।
এমএম

1
একটি গৌণ সমস্যা হ'ল যদিও সি ++ স্ট্যান্ডার্ডটি এটি বলে মনে হচ্ছে যে <math.h>এতে অতিরিক্ত অতিরিক্ত বোঝাও অন্তর্ভুক্ত রয়েছে; অনুশীলনে এটি দেখা যাচ্ছে যে ফর্মটি <cmath>ব্যবহার না করা অবধি সমস্ত বড় সংকলকরা ওভারলোডগুলি অন্তর্ভুক্ত করে না ।
এমএম

38
#include <stdio.h>

int main(void)
{
    printf("%d\n", (int)sizeof('a'));
    return 0;
}

সি- sizeof(int)তে, বর্তমান সিস্টেমে এর মান যা রয়েছে তা মুদ্রণ করে, যা সাধারণত 4বেশিরভাগ সিস্টেমে সাধারণত ব্যবহৃত হয়।

সি ++ এ, এটি অবশ্যই 1 মুদ্রণ করবে।


3
হ্যাঁ, আমি আসলে এই কৌশলটির সাথে পরিচিত ছিলাম, কারণ 'গ' সি-তে একটি অন্তর্নিহিত, এবং সি ++ তে একটি চর ছিল তবে এটি এখানে তালিকাভুক্ত করা এখনও ভাল।
শন

9
এটি একটি আকর্ষণীয় সাক্ষাত্কারের প্রশ্নটি তৈরি করবে - বিশেষত এমন লোকদের জন্য যা তাদের সিভিতে সি / সি ++ বিশেষজ্ঞ রাখে
মার্টিন বেকেট

2
ধরণের আন্ডারহ্যান্ডড যদিও। আকারের পুরো উদ্দেশ্যটি তাই কোনও প্রকারের আকারটি ঠিক কতটা আপনার জানা দরকার।
দানা দ্য সনে

13
সিতে মান বাস্তবায়ন সংজ্ঞায়িত হয় এবং 1 সম্ভাবনা। (সি ++ তে এটি যেমন বলা হয়েছে তেমন 1 টি মুদ্রণ করতে হবে))
উইন্ডোজ প্রোগ্রামার

3
আসলে এটি উভয় ক্ষেত্রেই অপরিবর্তিত আচরণ করেছে। %dএর জন্য সঠিক বিন্যাস নির্দিষ্টকরণকারী নয় size_t
আর .. গীটহাব বন্ধ করুন ICE

37

আরেকটি sizeofফাঁদ: বুলিয়ান এক্সপ্রেশন।

#include <stdio.h>
int main() {
    printf("%d\n", (int)sizeof !0);
}

এটি sizeof(int)সি এর সমান , কারণ অভিব্যক্তিটি প্রকারের int, তবে সাধারণত সি ++ এ 1 হয় (যদিও এটির প্রয়োজন হয় না)। অনুশীলনে তারা প্রায় সবসময় আলাদা হয়।


6
এক !একটি জন্য যথেষ্ট হওয়া উচিত bool
আলেক্সি ফ্রুঞ্জ

4
!! বুলিয়ান রূপান্তরকারী অপারেটরের
অন্তর্নিহিত

1
sizeof(0)হয় 4উভয় সি এবং সি ++ কারণ 0একটি পূর্ণসংখ্যা rvalue হয়। sizeof(!0)হয় 4সি এবং 1সি ++ হবে। লজিকাল নয়টি টাইপের বুলের অপারেন্ডগুলিতে কাজ করে। যদি মান মান হয় তবে এটি স্পষ্টত 0রূপান্তরিত হয় false(একটি মূল মূল্য), তবে এটি উল্টানো হয়, ফলস্বরূপ true। উভয় trueএবং falseC ++ bool, rvalues এবং sizeof(bool)হয় 1। তবে সিতে যা !0মূল্যায়ন করে তা 1টাইপ ইন্টের একটি মূল্য। সি প্রোগ্রামিং ভাষার ডিফল্টরূপে কোনও বুল ডেটা টাইপ নেই।
গ্যালাক্সি

26

সি ++ প্রোগ্রামিং ভাষা (তৃতীয় সংস্করণ) তিনটি উদাহরণ দেয়:

  1. আকার হিসাবে ('এ'), যেমন অ্যাডাম রোজেনফিল্ড উল্লিখিত;

  2. // মন্তব্য লুকানো কোড তৈরি করতে ব্যবহৃত হচ্ছে:

    int f(int a, int b)
    {
        return a //* blah */ b
            ;
    }
  3. কাঠামো ইত্যাদি আপনার উদাহরণ হিসাবে যেমন স্কোপগুলিতে জিনিস লুকিয়ে রাখে।



21

সি ++ স্ট্যান্ডার্ড দ্বারা তালিকাবদ্ধ অন্য একটি:

#include <stdio.h>

int x[1];
int main(void) {
    struct x { int a[2]; };
    /* size of the array in C */
    /* size of the struct in C++ */
    printf("%d\n", (int)sizeof(x)); 
}

সুতরাং আপনি প্যাডিং পার্থক্য পেতে?
v.oddou

আহ দুঃখিত আমি এটি পেয়েছি, xশীর্ষে আরও একটি আছে। আমি ভেবেছিলাম আপনি "অ্যারে a" বলেছেন।
v.oddou

20

সি ডিফল্ট ইনলাইন ফাংশনগুলি বহিরাগত স্কোপ থেকে যেখানে C ++ এ থাকে না।

নীচের দুটি ফাইল একসাথে সংকলন করলে জিএনইউ সি-র ক্ষেত্রে "আমি ইনলাইন আছি" মুদ্রণ হবে তবে সি ++ এর জন্য কিছুই নেই।

ফাইল 1

#include <stdio.h>

struct fun{};

int main()
{
    fun();  // In C, this calls the inline function from file 2 where as in C++
            // this would create a variable of struct fun
    return 0;
}

ফাইল 2

#include <stdio.h>
inline void fun(void)
{
    printf("I am inline\n");
} 

এছাড়াও, সি ++ পরোক্ষভাবে একইরূপে কোনো constবৈশ্বিক হিসাবে staticযদি না তা স্পষ্টভাবে ঘোষিত হয় extern, সি অসদৃশ যা externপূর্বনির্ধারিত।


আমি সত্যিই তা মনে করি না। সম্ভবত আপনি পয়েন্ট মিস করেছেন। এটি স্ট্রাক্ট সেন্টের সংজ্ঞা সম্পর্কে নয় যা কেবল কোডটি বৈধ সি ++ তৈরি করতে ব্যবহৃত হয়। মুল বক্তব্যটি এটি সি বনাম সি ++ এ ইনলাইন ফাংশনের বিভিন্ন আচরণকে হাইলাইট করে। বাহ্যিক ক্ষেত্রেও একই প্রযোজ্য। এর কোনওটিই সমাধানের কোনওটিতেই আলোচনা করা হয়নি।
fkl

2
ইনলাইন ফাংশনগুলির বিভিন্ন আচরণ কী এবং externএটি এখানে প্রদর্শিত হয়?
শেঠ কার্নেগি

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

12
@fayyazkl আচরণ দেখানো শুধুমাত্র (লুকআপ পার্থক্যের কারণ struct funবনাম fn) এবং ফাংশন ইনলাইন কিনা কিছুই করার আছে। আপনি inlineকোয়ালিফায়ার অপসারণ করলে ফলাফলটি অভিন্ন ।
অ্যালেক্স বি

3
আইএসও সিতে এই প্রোগ্রামটি অসুস্থ হয়ে পড়ে: inlineC99 পর্যন্ত যুক্ত করা হয়নি, তবে C99 fun()এ সুযোগের প্রোটোটাইপ ছাড়া ডাকা যাবে না। সুতরাং আমি ধরে নিই যে এই উত্তরটি কেবল জিএনইউ সি
এমএম

16
struct abort
{
    int x;
};

int main()
{
    abort();
    return 0;
}

সি ++ এ 0 এর প্রস্থান কোড বা 3 ডিগ্রি সেন্টিগ্রেডে ফিরে আসে

এই কৌশলটি সম্ভবত আরও আকর্ষণীয় কিছু করার জন্য ব্যবহার করা যেতে পারে তবে আমি কনস্ট্রাক্টর তৈরির কোনও ভাল পদ্ধতির কথা ভাবতে পারি না যা সি'র জন্য স্বচ্ছ হতে পারে I পরিবর্তে অ-বহনযোগ্য ফ্যাশনে যাই হোক না কেন:

struct exit
{
    int x;
};

int main()
{
    struct exit code;
    code.x=1;

    exit(code);

    return 0;
}

ভিসি ++ 2005 সি ++ মোডে এটি সংকলন করতে অস্বীকৃতি জানালেন, যদিও "প্রস্থান কোড" কীভাবে নতুন সংজ্ঞা দেওয়া হয়েছিল সে সম্পর্কে অভিযোগ করেছিলেন। (আমি মনে করি এটি একটি সংকলক বাগ, যদি না হঠাৎ কীভাবে প্রোগ্রাম করবেন তা ভুলে গেছি)) যদিও সি হিসাবে সংকলিত হওয়ার পরে এটি 1 এর প্রসেস প্রস্থান কোডের সাথে উপস্থিত হয়েছিল।


আপনার দ্বিতীয় উদাহরণ প্রস্থানটি ব্যবহার করে, দুর্ভাগ্যক্রমে, gcc বা g ++ এ সংকলন করে না। যদিও এটি একটি ভাল ধারণা।
শান

1
exit(code)স্পষ্টতই codeধরণের বৈকল্পিকের বৈধ ঘোষণা exit। ("সর্বাধিক ভেক্সিং পার্স" দেখুন, এটি একটি ভিন্ন তবে একই রকম সমস্যা)।
ব্যবহারকারী 253751

16
#include <stdio.h>

struct A {
    double a[32];
};

int main() {
    struct B {
        struct A {
            short a, b;
        } a;
    };
    printf("%d\n", sizeof(struct A));
    return 0;
}

এই প্রোগ্রামটি মুদ্রণ করে 128( 32 * sizeof(double)) একটি সি ++ সংকলক 4ব্যবহার করে এবং যখন সি সংকলক ব্যবহার করে সংকলিত হয় তখন।

এটি কারণ স্কোপ রেজোলিউশন ধারণাটি না সি। সি কাঠামোতে অন্যান্য কাঠামোতে অন্তর্ভুক্ত বাইরের কাঠামোর আওতায়।


এই এক আকর্ষণীয়! (আমি মনে করি আপনি 32*sizeof(double)32 এর চেয়ে বেশি :) এর অর্থ :))
ব্যবহারকারীর 354557

3
নোট আপনি UB পেয়ে থাকেন যে মুদ্রণ size_tসঙ্গে%d
phuclv

7

সি এবং সি ++ বিশ্বব্যাপী নেমস্পেসের মধ্যে পার্থক্যটি ভুলে যাবেন না। মনে করুন আপনার একটি foo.cpp আছে

#include <cstdio>

void foo(int r)
{
  printf("I am C++\n");
}

এবং একটি foo2.c

#include <stdio.h>

void foo(int r)
{
  printf("I am C\n");
}

এখন অনুমান করা আপনি একটি আছে main.c এবং main.cpp যা এই মত উভয় বর্ণন:

extern void foo(int);

int main(void)
{
  foo(1);
  return 0;
}

সি ++ হিসাবে সংকলিত হয়ে গেলে, এটি সি ++ বিশ্বব্যাপী নেমস্পেসে প্রতীকটি ব্যবহার করবে; সি তে এটি সি ব্যবহার করবে:

$ diff main.cpp main.c
$ gcc -o test main.cpp foo.cpp foo2.c
$ ./test 
I am C++
$ gcc -o test main.c foo.cpp foo2.c
$ ./test 
I am C

আপনি সংযোগ স্পেসিফিকেশন মানে?
user541686

নাম সি ++ নামের উপসর্গ এবং প্রত্যয় রয়েছে যখন সি নয়
কোফডেপলবার

নাম মাংলিং সি ++ নির্দিষ্টকরণের অংশ নয়। এটা কি সি নিষিদ্ধ?
21:25

5
এটি অপরিজ্ঞাত আচরণ (একাধিক সংজ্ঞা foo)। আলাদাভাবে "গ্লোবাল নেমস্পেস" নেই।
এমএম

4
int main(void) {
    const int dim = 5; 
    int array[dim];
}

এটি বরং অদ্ভুত যে এটি সি ++ এবং সি 99, সি 11, এবং সি 17 (যদিও সি 11, সি 17 এ alচ্ছিক) তে বৈধ; তবে সি 98 এ বৈধ নয়।

C99 + এ এটি একটি পরিবর্তনশীল-দৈর্ঘ্যের অ্যারে তৈরি করে, যার সাধারণ অ্যারেগুলির নিজস্ব বৈশিষ্ট্য রয়েছে কারণ এটি সংকলন-টাইম টাইপের পরিবর্তে রানটাইম টাইপ করে এবং সিটিতে sizeof arrayপূর্ণসংখ্যক ধ্রুবক প্রকাশ নয় C -+ এ টাইপটি সম্পূর্ণ স্থিতিশীল।


আপনি যদি এখানে একটি ইনিশিয়ালাইজার যুক্ত করার চেষ্টা করেন:

int main(void) {
    const int dim = 5; 
    int array[dim] = {0};
}

বৈধ সি ++ তবে সি নয়, কারণ ভেরিয়েবল-দৈর্ঘ্যের অ্যারেগুলিতে আরম্ভকারী থাকতে পারে না।


0

এটি সি এবং সি ++ এর লভ্য এবং মূল্যগুলি নিয়ে উদ্বেগ প্রকাশ করে।

সি প্রোগ্রামিং ল্যাঙ্গুয়েজে প্রাক-ইনক্রিমেন্ট এবং পোস্ট-ইনক্রিমেন্ট অপারেটর উভয়ই লভ্যালু নয়, মূল্য দেয়। এর অর্থ তারা =অ্যাসাইনমেন্ট অপারেটরের বাম দিকে থাকতে পারে না । এই দুটি বিবৃতি সিতে একটি সংকলক ত্রুটি দেবে:

int a = 5;
a++ = 2;  /* error: lvalue required as left operand of assignment */
++a = 2;  /* error: lvalue required as left operand of assignment */

তবে সি ++ এ, প্রি-ইনক্রিমেন্ট অপারেটর একটি মূল্য দেয় , যখন পোস্ট-ইনক্রিমেন্ট অপারেটর একটি মূল্য দেয়। এর অর্থ হ'ল প্রাক-ইনক্রিমেন্ট অপারেটরের সাথে একটি এক্সপ্রেশন =অ্যাসাইনমেন্ট অপারেটরের বাম পাশে স্থাপন করা যেতে পারে !

int a = 5;
a++ = 2;  // error: lvalue required as left operand of assignment
++a = 2;  // No error: a gets assigned to 2!

এখন কেন এমন হয়? পোস্ট-ইনক্রিমেন্টের পরে ভেরিয়েবল ইনক্রিমেন্ট হয় এবং এটি ইনক্রিমেন্ট হওয়ার আগে যেমন ছিল তেমন চলকটি দেয় returns এটি আসলে কেবল একটি মূল্যায়ন। ভেরিয়েবল এ এর ​​পূর্বের মানটি একটি অস্থায়ী হিসাবে একটি রেজিস্টারে অনুলিপি করা হয় এবং তারপরে একটি বৃদ্ধি করা হয়। তবে ক এর পূর্বের মানটি প্রকাশের মাধ্যমে ফিরে আসে, এটি একটি মূল্য। এটি ভেরিয়েবলের বর্তমান সামগ্রীর প্রতিনিধিত্ব করে না।

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

int x = a;
int x = ++a;

যেহেতু প্রাক-ইনক্রিমেন্টটি একটি মূল্যকে ফেরত দেয়, আমরা এটিতেও কিছু বরাদ্দ করতে পারি। নিম্নলিখিত দুটি বিবৃতি অভিন্ন। দ্বিতীয় অ্যাসাইনমেন্টে, প্রথমে একটি বৃদ্ধি করা হয়, তারপরে এর নতুন মান 2 দিয়ে ওভাররাইট করা হয়।

int a;
a = 2;
++a = 2;  // Valid in C++.

3
এখানে "বৈধ ইন সি" নেই।
o11c

0

খালি কাঠামোগুলির আকার 0 ডিগ্রি সেন্টিগ্রেড এবং 1 ++++ থাকে:

#include <stdio.h>

typedef struct {} Foo;

int main()
{
    printf("%zd\n", sizeof(Foo));
    return 0;
}

1
না, পার্থক্য সি না যে না খালি কাঠামো থাকবে, যার ফলে কম্পাইলার এক্সটেনশান হিসাবে ছাড়া, অর্থাত এই কোড মিলছে না "উভয় সি এবং সি ++ বৈধ হল"
Antti Haapala
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.