আমি এটিকে গুগলে টাইপ করেছি তবে কেবল সি ++ তে হাওটো পেয়েছি,
এটি সি তে কীভাবে করবেন?
আমি এটিকে গুগলে টাইপ করেছি তবে কেবল সি ++ তে হাওটো পেয়েছি,
এটি সি তে কীভাবে করবেন?
উত্তর:
সি-তে কোনও ব্যতিক্রম নেই সিটিতে ত্রুটিগুলি ফাংশনটির ফিরে আসা মান, প্রক্রিয়াটির প্রস্থান মূল্য, প্রক্রিয়াতে সংকেত ( প্রোগ্রাম ত্রুটি সংকেত (জিএনইউ লিবিসি) ) বা সিপিইউ হার্ডওয়্যার বিঘ্ন (বা অন্যান্য বিজ্ঞপ্তি) দ্বারা জানানো হয় ত্রুটি থাকলে সিপিইউ গঠন করে) ( প্রসেসর কীভাবে শূন্য দ্বারা বিভাগের কেস পরিচালনা করে )।
ব্যতিক্রমগুলি সি ++ এবং অন্যান্য ভাষায় যদিও সংজ্ঞায়িত করা হয়। সি ++ এ ব্যতিক্রম হ্যান্ডলিং সি ++ স্ট্যান্ডার্ড "এস .15 ব্যতিক্রম হ্যান্ডলিং" এ সুনির্দিষ্ট করা হয়েছে, সি স্ট্যান্ডার্ডে কোনও সমমানের বিভাগ নেই।
main
একটি .c
ফাইল সহ একটি প্রোগ্রামে কিছু সি ++ অন্তর্ভুক্ত থাকতে পারে, এবং তাই ব্যতিক্রমগুলি প্রোগ্রামে ছুঁড়ে ফেলা এবং ধরা যেতে পারে তবে সি কোডের অংশগুলি সি ব্যতীত ফেলে দেওয়া এবং ধরা প্রায়শই সিটিতে লিখিত ফাংশনগুলির উপর নির্ভর করে ব্যতীত এই সমস্ত কিছু সম্পর্কে অজ্ঞ থাকবে will যা সি ++ লাইব্রেরিতে থাকে। সি ব্যবহার করা হয়েছে কারণ আপনি throw
ব্যতিক্রম নিজেই নিক্ষেপ করার জন্য ডাকা ফাংশনটি ঝুঁকিপূর্ণ করতে পারবেন না । যদিও একটি সংকলক / গ্রন্থাগার / লক্ষ্য ব্যতীত ছোঁড়া / ধরতে ব্যতিক্রম নির্দিষ্ট উপায় থাকতে পারে। তবে একটি ক্লাস উদাহরণ নিক্ষেপ করার নিজস্ব সমস্যা থাকবে।
সি তে আপনি সংজ্ঞায়িত setjmp()
এবং longjmp()
ফাংশনগুলির সংমিশ্রণটি ব্যবহার করতে পারেন setjmp.h
। উইকিপিডিয়া থেকে উদাহরণ
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void) {
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp
// was called - making setjmp now return 1
}
void first(void) {
second();
printf("first\n"); // does not print
}
int main() {
if ( ! setjmp(buf) ) {
first(); // when executed, setjmp returns 0
} else { // when longjmp jumps back, setjmp returns 1
printf("main"); // prints
}
return 0;
}
দ্রষ্টব্য: আমি আসলে আপনাকে পরামর্শ দেব যে তারা সি ++ (স্থানীয় বস্তুর ধ্বংসকারীদের ডাকা হবে না) নিয়ে ভয়ঙ্কর কাজ করার কারণে সেগুলি ব্যবহার না করার জন্য এবং কী চলছে তা বোঝা সত্যিই শক্ত। পরিবর্তে কিছু ধরণের ত্রুটি ফিরিয়ে দিন।
if()
। আমি এতে কোনও বিপদ দেখতে পাচ্ছি না; এখানে অন্য কেউ করতে পারেন?
সরল পুরানো সি বাস্তবে ব্যাতিক্রমকে সমর্থন করে না।
আপনি বিকল্প ত্রুটি পরিচালনার কৌশলগুলি ব্যবহার করতে পারেন, যেমন:
FALSE
এবং একটি last_error
ভেরিয়েবল বা ফাংশন ব্যবহার করে ।Http://en.wikibooks.org/wiki/C_Programming/Error_handling দেখুন ।
GetLastError()
উইন্ডোজ এপিআই তে
সি -তে কোনও অন্তর্নির্মিত ব্যতিক্রম ব্যবস্থা নেই; আপনাকে ব্যতিক্রম এবং তাদের শব্দার্থবিজ্ঞানের অনুকরণ করতে হবে । সাধারণত setjmp
এবং উপর নির্ভর করে এটি অর্জন করা হয় longjmp
।
চারপাশে বেশ কয়েকটি গ্রন্থাগার রয়েছে এবং আমি আরও একটি বাস্তবায়ন করছি। একে ব্যতিক্রম 4c বলা হয় ; এটি বহনযোগ্য এবং বিনামূল্যে। আপনি এটি একবার দেখে নিতে পারেন এবং এটি আপনার অন্যান্য ক্ষেত্রে সবচেয়ে উপযুক্ত কিনা তা দেখতে অন্যান্য বিকল্পের সাথে তুলনা করতে পারেন।
সি সি ++ ব্যতিক্রম ছুঁড়ে ফেলতে সক্ষম, এগুলি যাইহোক মেশিন কোড। উদাহরণস্বরূপ, বার
// begin bar.c
#include <stdlib.h>
#include <stdint.h>
extern void *__cxa_allocate_exception(size_t thrown_size);
extern void __cxa_throw (void *thrown_exception, void* *tinfo, void (*dest) (void *) );
extern void * _ZTIl; // typeinfo of long
int bar1()
{
int64_t * p = (int64_t*)__cxa_allocate_exception(8);
*p = 1976;
__cxa_throw(p,&_ZTIl,0);
return 10;
}
// end bar.c
a.cc এ,
#include <stdint.h>
#include <cstdio>
extern "C" int bar1();
void foo()
{
try{
bar1();
}catch(int64_t x){
printf("good %ld",x);
}
}
int main(int argc, char *argv[])
{
foo();
return 0;
}
এটি সংকলন করতে
gcc -o bar.o -c bar.c && g++ a.cc bar.o && ./a.out
আউটপুট
good 1976
http://mentore এম্বেড.github.io/cxx-abi/abi-eh.html সম্পর্কে আরও বিশদ তথ্য আছে __cxa_throw
।
এটি পোর্টেবল কিনা তা আমি নিশ্চিত নই এবং আমি এটি লিনাক্সে 'gcc-4.8.2' দিয়ে পরীক্ষা করি।
_ZTII
অর্থ typeinfo for long
, যেমন echo '_ZTIl' | c++filt
। এটি জি ++ ম্যাংলিং স্কিম।
এই প্রশ্নটি বেশ পুরানো, তবে আমি কেবল এটির পিছনে হোঁচট খেয়েছি এবং ভেবেছিলাম যে আমি কোনও কৌশল ভাগ করব: শূন্য দ্বারা ভাগ করুন, বা একটি নাল পয়েন্টারকে অবজ্ঞা করুন।
প্রশ্নটি কেবল "কীভাবে নিক্ষেপ করা যায়", কীভাবে ধরবেন না, এমনকি কোনও নির্দিষ্ট ধরণের ব্যতিক্রম কীভাবে ছুঁড়বেন তা নয়। আমার বহু বছর আগে পরিস্থিতি ছিল যেখানে আমাদের সি ++ এ ধরা পড়ার জন্য একটি ব্যতিক্রম ট্রিগার করতে হবে। বিশেষত, আমাদের মাঝে মাঝে "খাঁটি ভার্চুয়াল ফাংশন কল" ত্রুটির খবর পাওয়া যায় এবং কিছু ছুঁড়ে ফেলার জন্য সি রানটাইমের _পিউরেকল ফাংশনকে বোঝানো দরকার। সুতরাং আমরা আমাদের নিজস্ব_পিউরাকল ফাংশন যুক্ত করেছি যা শূন্য দ্বারা বিভক্ত হয়ে গেছে, এবং আমরা একটি ব্যতিক্রম পেয়েছি যা আমরা সি ++ তে ধরতে পারি এবং এমন কি জিনিস কোথায় ভুল হয়েছে তা দেখার জন্য কিছু স্ট্যাক মজাদার ব্যবহার করি।
এমএসভিসির সাথে উইন এ রয়েছে __try ... __except ...
তবে এটি সত্যই ভয়ঙ্কর এবং আপনি যদি এটিকে সম্ভবত এড়াতে পারেন তবে আপনি এটি ব্যবহার করতে চান না। বলাই ভাল যে এর ব্যতিক্রম নেই।
সি এর ব্যতিক্রম নেই।
বিভিন্ন হ্যাকি বাস্তবায়ন রয়েছে যা এটি করার চেষ্টা করে (একটি উদাহরণ: http://adomas.org/excc/ )।
অসংখ্য থ্রেডে উল্লিখিত হিসাবে, এটি করার "স্ট্যান্ডার্ড" উপায়টি সেটজেম্প / লংজ্যাম্প ব্যবহার করছে। আমি https://github.com/psevon/exception-and-raii-in-c- তে এর পরে আর একটি সমাধান পোস্ট করেছি এটি আমার জ্ঞানের একমাত্র সমাধান যা বরাদ্দকৃত সংস্থানগুলি স্বয়ংক্রিয়ভাবে পরিষ্কারের উপর নির্ভর করে। এটি অনন্য এবং ভাগ করা স্মার্টপোয়েন্টারগুলি প্রয়োগ করে এবং মধ্যবর্তী ফাংশনগুলি ব্যতিক্রমগুলি ধরে না ফেলে এবং তাদের স্থানীয়ভাবে বরাদ্দকৃত সম্পদগুলি সঠিকভাবে পরিষ্কার করার অনুমতি দেয় properly
সি ব্যতিক্রমগুলি সমর্থন করে না। আপনি আপনার সি কোডটি ভিজ্যুয়াল স্টুডিও বা জি ++ দিয়ে সি ++ হিসাবে সংকলনের চেষ্টা করতে পারেন এবং এটি যেমন রয়েছে তেমন সংকলন করবে কিনা তা দেখতে পারেন। বেশিরভাগ সি অ্যাপ্লিকেশনগুলি বড় পরিবর্তন ছাড়াই সি ++ হিসাবে সংকলন করবে এবং আপনি তারপরে ... চেষ্টা বাক্যটি ব্যবহার করতে পারেন।
আপনি যদি হ্যাপি পাথ ডিজাইনের প্যাটার্ন (যেমন এম্বেডেড ডিভাইসের জন্য) কোড লিখে থাকেন তবে আপনি অপারেটর "গোটো" এর সাথে ব্যতিক্রম ত্রুটি প্রক্রিয়াকরণ (ওরফে ডিফারিং বা শেষ পর্যন্ত এমুলেশন) সিমুলেট করতে পারেন।
int process(int port)
{
int rc;
int fd1;
int fd2;
fd1 = open("/dev/...", ...);
if (fd1 == -1) {
rc = -1;
goto out;
}
fd2 = open("/dev/...", ...);
if (fd2 == -1) {
rc = -1;
goto out;
}
// Do some with fd1 and fd2 for example write(f2, read(fd1))
rc = 0;
out:
//if (rc != 0) {
(void)close(fd1);
(void)close(fd2);
//}
return rc;
}
এটি আসলে ব্যতিক্রম হ্যান্ডলারটি করে না তবে ফুকশন প্রস্থান করার সময় ত্রুটিটি হ্যান্ডেল করার জন্য আপনাকে একটি উপায় অবলম্বন করে।
পিএস আপনার কেবল একই বা আরও গভীর স্কোপগুলি থেকে সতর্কতার সাথে ব্যবহার করা উচিত এবং ভেরিয়েবলের ঘোষণাকে কখনই লাফাতে না পারে।
এরিক রবার্টস সি দ্বারা ব্যতিক্রম কার্যকর করছে
সি ইন্টারফেস এবং হ্যানসন দ্বারা বাস্তবায়ন এর অধ্যায় 4 ।
ডগ মোইনের ত্রুটি পরিচালনা করার একটি শৃঙ্খলা
সি তে ব্যতিক্রম বাস্তবায়ন (ই রবার্টসের নিবন্ধের বিবরণ)