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

int current = 0;

void sigint_handle(int sig) {
    printf("sigint: %d\n", current);
}

int main()
{
    sigset(SIGINT, sigint_handle);

    while (1) {
        current++;
        // if (current % 1000000 == 0) printf("hey\n");
    }

    return 0;
}

जीसीसी 7.2.0 का उपयोग करके अनुकूलन स्तर -O0 के साथ संकलित, यह कोड अपेक्षा के अनुरूप काम करता है। हालांकि, किसी भी अन्य अनुकूलन स्तर के साथ, सिगिंट भेजने से हर बार sigint: 0 प्रिंट आउट हो जाएगा। आउटपुट लाइन के असम्बद्ध होने पर यह ऑप्टिमाइज़ेशन की परवाह किए बिना सही ढंग से काम करेगा।

क्या मुझे सिग्नल के बारे में कुछ याद आ रहा है, क्या यह जीसीसी में एक बग है या यह इच्छित व्यवहार है (और यदि हां, तो क्यों?)?

1
user2244484 25 अक्टूबर 2017, 17:52
current को volatile sigatomic_t प्रकार के रूप में घोषित करें।
 – 
John Bollinger
25 अक्टूबर 2017, 17:54
1
आप और क्या याद कर रहे हैं? सिग्नल हैंडलर में printf() को कॉल करना अपरिभाषित व्यवहार है। सिग्नल हैंडलर से केवल एसिंक-सिग्नल-सुरक्षित कार्यों को सुरक्षित रूप से बुलाया जा सकता है।
 – 
Andrew Henle
25 अक्टूबर 2017, 19:07

1 उत्तर

सबसे बढ़िया उत्तर

स्थिर भंडारण अवधि के साथ किसी ऑब्जेक्ट तक पहुंचना और सिग्नल हैंडलर से volatile sig_atomic_t के अलावा अन्य टाइप करना अपरिभाषित व्यवहार में परिणाम देता है। इसका स्रोत है (C11 के लिए):

7.14.1.1 सिग्नल फ़ंक्शन

[...]

5 यदि सिग्नल एबॉर्ट को कॉल करने या फ़ंक्शन बढ़ाने के परिणाम के अलावा अन्य होता है, तो व्यवहार अपरिभाषित होता है यदि सिग्नल हैंडलर स्थिर या थ्रेड स्टोरेज अवधि के साथ किसी ऑब्जेक्ट को संदर्भित करता है जो लॉक-फ्री परमाणु ऑब्जेक्ट नहीं है, इसके अलावा असाइन करके अस्थिर sig_atomic_t के रूप में घोषित किसी वस्तु का मान, या...

POSIX संभावित रूप से (भविष्य की संभावित दिशा, अभी तक तय नहीं) व्यवहार को थोड़ा और आराम की स्थिति में परिभाषित करेगा; कुछ अर्थों में यह गलती से पहले से ही एएस-सुरक्षित कार्यों के उपयोग के साथ कमियों के माध्यम से करता है। मेरे पास इस विषय के बारे में ऑस्टिन ग्रुप इश्यू ट्रैकर पर एक खुला मुद्दा है:

http://austingroupbugs.net/view.php?id=728

5
R.. GitHub STOP HELPING ICE 25 अक्टूबर 2017, 17:58