मैंने इसे Google में टाइप किया, लेकिन केवल C ++ में हॉवोस पाया,
इसे C में कैसे करें?
मैंने इसे Google में टाइप किया, लेकिन केवल C ++ में हॉवोस पाया,
इसे C में कैसे करें?
जवाबों:
सी में कोई अपवाद नहीं हैं। सी में त्रुटियों को फ़ंक्शन के लौटाए गए मूल्य, प्रक्रिया के निकास मूल्य, प्रक्रिया के संकेतों ( प्रोग्राम त्रुटि सिग्नल (GNU libc) ) या सीपीयू हार्डवेयर रुकावट (या अन्य अधिसूचना) द्वारा अधिसूचित किया जाता है। यदि सीपीयू है तो त्रुटि उत्पन्न होती है) ( कैसे प्रोसेसर शून्य से विभाजन के मामले को संभालता है )।
अपवादों को C ++ और अन्य भाषाओं में परिभाषित किया गया है। C ++ में एक्सेप्शन हैंडलिंग C ++ मानक "S.15 एक्सेप्शन हैंडलिंग" में निर्दिष्ट है, C मानक में कोई समान खंड नहीं है।
main
एक में .c
फ़ाइल, कुछ सी ++ शामिल कर सकते हैं और इसलिए अपवाद फेंक दिया जा सकता है और इस कार्यक्रम में फंस गए, लेकिन सी कोड अंश यह है कि अपवाद फेंकने को छोड़कर चल रहा के सभी से अनभिज्ञ बनी रहती है और पकड़ने अक्सर सी में लिखे कार्यों पर भरोसा करते हैं जो C ++ पुस्तकालयों में रहता है। C का उपयोग किया जाता है क्योंकि आप फ़ंक्शन 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;
}
नोट: मैं वास्तव में आपको सलाह दूंगा कि आप इनका उपयोग न करें क्योंकि वे C ++ के साथ भयानक काम करते हैं (स्थानीय वस्तुओं के विनाशकों को नहीं बुलाया जाएगा) और यह समझना मुश्किल है कि क्या चल रहा है। इसके बजाय किसी प्रकार की त्रुटि लौटाएं।
if()
। मैं इसमें कोई खतरा नहीं देख सकता; यहाँ कोई और हो सकता है?
सादा पुराना सी वास्तव में मूल रूप से अपवादों का समर्थन नहीं करता है।
आप वैकल्पिक त्रुटि हैंडलिंग रणनीतियों का उपयोग कर सकते हैं, जैसे:
FALSE
एक last_error
चर या फ़ंक्शन का उपयोग करके वापस लौटना ।Http://en.wikibooks.org/wiki/C_Programming/Error_handling देखें ।
GetLastError()
विंडोज़ एपीआई में।
सी में कोई अंतर्निहित अपवाद तंत्र नहीं है; आपको अपवादों और उनके शब्दार्थों का अनुकरण करने की आवश्यकता है । यह आमतौर पर setjmp
और पर भरोसा करके हासिल किया जाता है longjmp
।
आसपास काफी पुस्तकालय हैं, और मैं अभी तक एक और को लागू कर रहा हूं। इसे अपवाद 4c कहा जाता है ; यह पोर्टेबल और मुफ्त है। आप इसे देख सकते हैं, और अन्य विकल्पों के खिलाफ तुलना करके देख सकते हैं कि कौन सा आपको सबसे अधिक पसंद है।
C C ++ अपवाद को फेंकने में सक्षम है, वे वैसे भी मशीन कोड हैं। उदाहरण के लिए, bar.c में
// 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
in.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://mentorembedded.github.io/cxx-abi/abi-eh.html के बारे में अधिक विस्तार से जानकारी है __cxa_throw
।
मुझे यकीन नहीं है कि यह पोर्टेबल है या नहीं, और मैं इसे 'gcc-4.8.2' के साथ लिनक्स पर परीक्षण करता हूं।
_ZTII
साधन typeinfo for long
, जैसे echo '_ZTIl' | c++filt
। यह जी ++ प्रबंध योजना है।
यह सवाल सुपर पुराना है, लेकिन मैं अभी इसके पार गया और सोचा कि मैं एक तकनीक साझा करूंगा: शून्य से विभाजित करें, या एक शून्य सूचक को निष्क्रिय करें।
सवाल बस "कैसे फेंकना है", न कि कैसे पकड़ना है, या एक विशेष प्रकार के अपवाद को कैसे फेंकना है। मेरे पास एक ऐसी स्थिति थी, जहां हमें C ++ में पकड़े जाने के लिए C से एक अपवाद को ट्रिगर करने की आवश्यकता थी। विशेष रूप से, हमारे पास "शुद्ध आभासी फ़ंक्शन कॉल" त्रुटियों की कभी-कभार रिपोर्ट थी, और कुछ को फेंकने के लिए सी रनटाइम के _purecall फ़ंक्शन को समझाने की आवश्यकता थी। इसलिए हमने अपने स्वयं के _purecall फ़ंक्शन को जोड़ा, जो शून्य से विभाजित होता है, और बूम होता है, हमें एक अपवाद मिला जिसे हम C ++ पर पकड़ सकते हैं, और यहां तक कि कुछ स्टैक मस्ती का उपयोग करके देख सकते हैं कि चीजें कहां गलत हुईं।
MSVC के साथ जीत पर वहाँ __try ... __except ...
वास्तव में भयानक है और आप इसका उपयोग नहीं करना चाहते हैं यदि आप संभवतः इससे बच सकते हैं। यह कहना बेहतर है कि कोई अपवाद नहीं हैं।
C में अपवाद नहीं हैं।
विभिन्न हैके कार्यान्वयन हैं जो इसे करने की कोशिश करते हैं (उदाहरण के लिए: http://adomas.org/excc/ )।
जैसा कि कई सूत्र में बताया गया है, ऐसा करने का "मानक" तरीका सेटजम्प / लॉन्गजम्प का उपयोग कर रहा है। मैंने अभी तक https://github.com/psevon/exception-and-raii-in-c पर इस तरह का एक और समाधान पोस्ट किया है, यह मेरे ज्ञान का एकमात्र समाधान है जो आवंटित संसाधनों के स्वचालित सफाई पर निर्भर करता है। यह अद्वितीय और साझा किए गए स्मार्टपॉइंटर्स को लागू करता है, और मध्यवर्ती कार्यों को अपवादों को पकड़ने के बिना गुजरने देता है और अभी भी अपने स्थानीय रूप से आवंटित संसाधनों को ठीक से साफ करता है।
C अपवादों का समर्थन नहीं करता है। आप अपने सी कोड को विजुअल स्टूडियो या जी ++ के साथ सी ++ के रूप में संकलित करने की कोशिश कर सकते हैं और देख सकते हैं कि क्या यह संकलन है। अधिकांश सी एप्लिकेशन प्रमुख परिवर्तनों के बिना C ++ के रूप में संकलित करेंगे, और आप तब कोशिश कर सकते हैं ... सिंटैक्स को पकड़ें।
यदि आप हैप्पी पाथ डिज़ाइन पैटर्न (यानी एम्बेडेड डिवाइस के लिए) के साथ कोड लिखते हैं, तो आप ऑपरेटर "गोटो" के साथ अपवाद त्रुटि प्रसंस्करण (उर्फ ख़राबी या अंत में अनुकरण) का अनुकरण कर सकते हैं।
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;
}
यह वास्तव में हैंडलर को अपवाद नहीं करता है, लेकिन यह आपको fucntion निकास पर त्रुटि को संभालने का एक तरीका है।
पुनश्च आप केवल एक या अधिक गहरी स्कैप से ही गोटो का सावधानीपूर्वक उपयोग करें और कभी भी चर घोषणा न करें।