चूंकि आप अपरिभाषित व्यवहार का आह्वान कर रहे हैं, इसलिए एक कंपाइलर को क्रैश करने के लिए ठीक है और दूसरा काम करने के लिए ठीक है। दोनों सही हैं - यह अपरिभाषित व्यवहार की सुंदरता है।
समस्या यह है कि एक सहेजा गया संदर्भ - jmp_buf
- केवल तब तक मान्य रहता है जब इसे setjmp()
नामक फ़ंक्शन को वापस नहीं किया जाता है।
C99 मानक (अब वर्तमान मानक है, लेकिन यह शब्द काफी बदल गया है की संभावना नहीं है) का कहना है:
§7.13.2.1 longjmp
समारोह
longjmp
समारोह बचाया वातावरण पुनर्स्थापित करता है setjmp
मैक्रो के हालिया आमंत्रण के साथ jmp_buf
तर्क के साथ प्रोग्राम के उसी आमंत्रण में मैक्रो। अगर ऐसी कोई मंगलाचरण किया गया है, या युक्त setjmp
मैक्रो के आह्वान समारोह अंतरिम में निष्पादन 208) समाप्त कर दिया है, या यदि setjmp
मैक्रो की मंगलाचरण variably साथ एक पहचानकर्ता के दायरे के भीतर था संशोधित प्रकार और निष्पादन ने अंतरिम में उस दायरे को छोड़ दिया है, व्यवहार अपरिभाषित है।
208) उदाहरण के लिए, एक return
बयान को क्रियान्वित करने या क्योंकि एक और longjmp
कॉल नेस्टेड कॉल के सेट में पहले एक समारोह में एक setjmp
मंगलाचरण के लिए एक हस्तांतरण का कारण बना है द्वारा।
आपका कोड action_1()
से बाहर निकलने है लगभग तुरंत, प्रतिपादन jmp_buf
setjmp()
बेकार ने बचा लिया।
मैं कुछ साल पहले setjmp()
और longjmp()
का यह छोटा प्रदर्शन बनाया। यह आपकी मदद कर सकता है।
/*
@(#)File: $RCSfile: setjmp.c,v $
@(#)Version: $Revision: 1.1 $
@(#)Last changed: $Date: 2009/10/01 16:41:04 $
@(#)Purpose: Demonstrate setjmp() and longjmp()
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 2009
*/
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
static jmp_buf target_location;
static void do_something(void)
{
static int counter = 0;
if (++counter % 10 == 0)
printf("---- doing something: %3d\n", counter);
if (counter % 1000 == 0)
{
printf("||-- doing_something: calling longjmp() with value -1\n");
longjmp(target_location, -1);
}
}
static void do_something_else(int i, int j)
{
printf("-->> do_something_else: (%d,%d)\n", i, j);
do_something();
if (i > 2 && j > 2 && j % i == 2)
{
printf("||-- do_something_else: calling longjmp() with value %d\n", (i + j) % 100);
longjmp(target_location, (i + j) % 100);
}
printf("<<-- do_something_else: (%d,%d)\n", i, j);
}
static void doing_stuff(void)
{
int i;
printf("-->> doing_stuff()\n");
for (i = rand() % 15; i < 30; i++)
{
int j;
do_something();
for (j = rand() % 10; j < 20; j++)
{
do_something_else(i, j);
}
}
printf("<<-- doing_stuff()\n");
}
static void manage_setjmp(void)
{
printf("-->> manage_setjmp()\n");
switch (setjmp(target_location))
{
case 0:
/* Initial return - get on with doing stuff */
doing_stuff();
break;
case -1:
/* Error return - terminate */
printf("<<-- manage_setjmp() - error return from setjmp()\n");
return;
default:
/* NB: not officially possible to assign the return from setjmp() */
printf("---- manage_setjmp() - non-error return from setjmp()\n");
doing_stuff();
break;
}
printf("<<-- manage_setjmp()\n");
}
int main(void)
{
printf("-->> main()\n");
manage_setjmp();
printf("<<-- main()\n");
return(0);
}
स्रोत
2011-12-25 07:42:34
मैं कैसे setjmp/longjmp वास्तव में अनुकूलक बँधा हुआ के बारे में थोड़ी देर पहले एक लेख पढ़ा है, और एक बार वे इसके बारे में कार्यक्रम छुटकारा पा लिया है कि वे काफी तेज पर काम कर रहे थे। – Bill
प्रश्न: एमएसवीसी ++ का संस्करण क्या है? प्रश्न: बिल्कुल यह कहां दुर्घटनाग्रस्त हो गया? क्या आपने विजुअल स्टूडियो डीबगर में चलाने का प्रयास किया था? प्रश्न: क्या आपके एमएसवीसी ++ संकलन में कोई चेतावनी या त्रुटियां थीं? – paulsm4
एमएसवीसी का मेरा संस्करण 2008 है। Longjmp में दुर्घटना। हाँ। संकलन पर कोई त्रुटि और चेतावनी नहीं है। यह एक रनटाइम त्रुटि – TZW