2012-07-18 21 views
10

क्या यह मानना ​​सुरक्षित है कि static_cast कभी अपवाद नहीं फेंक देगा?क्या static_cast C++ में अपवाद फेंक सकता है?

एनम कास्ट करने के लिए एक इंट के लिए, यह अमान्य होने पर भी एक अपवाद नहीं फेंक दिया जाता है। क्या मैं इस व्यवहार पर भरोसा कर सकता हूं? यह निम्नलिखित कोड काम करता है।

enum animal { 
    CAT = 1, 
    DOG = 2 
}; 

int y = 10; 
animal x = static_cast<animal>(y); 
+0

स्रोत और गंतव्य प्रकारों के आधार पर, static_cast का परिणाम अपरिभाषित व्यवहार हो सकता है, जिसमें अपवाद फेंकना शामिल हो सकता है। –

+1

यह पूछना बेहतर हो सकता है, क्या यह एक अपवाद फेंक सकता है जबकि कार्यक्रम एक अच्छी तरह से परिभाषित राज्य में है। बेशक यूबी सैद्धांतिक रूप से अपवाद फेंक सकता है, लेकिन यूबी सैद्धांतिक रूप से आपके हार्ड ड्राइव को भी प्रारूपित कर सकता है। – Wyzard

+0

@ जेरीकॉफिन: मानक 5.2.9 केवल इतना कहता है कि कुछ नतीजों को अपरिभाषित किया जा सकता है, और ऐसे परिणामों के बाद के उपयोग में अपरिभाषित व्यवहार हो सकता है, लेकिन स्वयं को कास्ट से अपरिभाषित व्यवहार का कोई स्पष्ट उल्लेख नहीं है। क्या मैं कुछ भूल रहा हूँ? –

उत्तर

13

इस विशेष प्रकार के कास्ट (गणना प्रकार के अभिन्न अंग के लिए), एक अपवाद फेंक दिया जा सकता है।

सी ++ मानक 5.2.9 स्टेटिक डाली [expr.static.cast] पैरा 7

अभिन्न या गणना प्रकार का मान स्पष्ट रूप से एक गणना प्रकार में बदला जा सकता। मूल्य मान अपरिवर्तित है यदि मूल मान गणना मूल्यों (7.2) की सीमा के भीतर है। अन्यथा, जिसके परिणामस्वरूप गणना मूल्य अनिर्दिष्ट/अपरिभाषित है (सी ++ 17 के बाद से)।

ध्यान दें कि जब से सी ++ 17 जैसे रूपांतरण वास्तव में अपरिभाषित व्यवहार, में परिणाम हो सकता है एक अपवाद फेंक शामिल हो सकते हैं।

दूसरे शब्दों में, static_cast के अपने विशेष उपयोग एक पूर्णांक से एक प्रगणित मूल्य प्राप्त करने के, जब तक सी ++ 17 और हमेशा ठीक ठीक है अगर आप किसी तरह का माध्यम लगता है कि पूर्णांक वास्तव में एक वैध enumerated मूल्य का प्रतिनिधित्व करता बनाने इनपुट सत्यापन प्रक्रिया।

कभी कभी इनपुट सत्यापन प्रक्रिया पूरी तरह से, एक static_cast की आवश्यकता समाप्त तो जैसे:

animal GetAnimal(int y) 
{ 
    switch(y) 
    { 
    case 1: 
     return CAT; 
    case 2: 
     return DOG; 
    default: 
     // Do something about the invalid parameter, like throw an exception, 
     // write to a log file, or assert() it. 
    } 
} 

, ऊपर संरचना की तरह कुछ प्रयोग करने पर विचार है कि यह कोई डाले की आवश्यकता है और आप सीमा मामलों को संभालने का अवसर देता है के लिए सही ढंग से।

6

static_cast डाली क्रम नहीं है, अगर कुछ casted नहीं किया जा सकता static_cast के बाद से अपवाद फेंक नहीं कर सकते, कोड compiles नहीं होगा। लेकिन अगर यह संकलित और कास्ट खराब है - परिणाम अपरिभाषित है।

+2

यह जरूरी नहीं है कि यह सच है। इसके परिणामस्वरूप स्रोत और गंतव्य प्रकारों के कुछ संयोजनों के लिए अपरिभाषित व्यवहार हो सकता है, और कहा * अपरिभाषित व्यवहार में अपवाद फेंकना शामिल हो सकता है *। –

+1

@ सिलिको में, ForEveR: क्या आप कुछ static_cast <> के अनिश्चित व्यवहार वाले अपने दावों के बारे में कुछ स्पष्टीकरण प्रदान कर सकते हैं? मानक 5.2.9 केवल कुछ नतीजों को परिभाषित किया जा सकता है, और इस तरह के परिणामों के बाद के उपयोग में अपरिभाषित व्यवहार हो सकता है, लेकिन कास्ट से अपरिभाषित * व्यवहार * का कोई स्पष्ट उल्लेख नहीं है। क्या मैं कुछ भूल रहा हूँ? –

+0

@ टोनीडेलॉय हाँ, परिणाम अपरिभाषित है, यूबी नहीं, धन्यवाद। – ForEveR

9

क्या यह मानना ​​सुरक्षित है कि static_cast कोई अपवाद नहीं फेंक देगा?

नहीं। उपयोगकर्ता द्वारा परिभाषित प्रकारों के लिए, कन्स्ट्रक्टर और/या रूपांतरण ऑपरेटर अपवाद फेंक सकता है, जिसके परिणामस्वरूप अच्छी तरह से परिभाषित व्यवहार होता है।

इस कार्यक्रम का उत्पादन पर विचार करें: (। यह उत्तर आपके प्रश्न में intenum करने के लिए रूपांतरण पर विशेष जोर देता है)

#include <iostream> 

struct A { 
    A(int) { throw 1; } 
}; 

int main() { 
    int y = 7; 
    try { 
    static_cast<A>(y); 
    } catch(...) { 
    std::cout << "caught\n"; 
    } 
} 
3

Enum कलाकारों के लिए एक पूर्णांक के लिए, एक अपवाद है अगर यह अमान्य है तो भी नहीं फेंक दिया। क्या मैं इस व्यवहार पर भरोसा कर सकता हूं? यह निम्नलिखित कोड काम करता है।

enum animal { CAT = 1, DOG = 2 }; 
int y = 10; 
animal x = static_cast<animal>(y); 

वास्तव में, enums अपनी परिभाषा में enumerations की सूची तक ही सीमित नहीं हैं, और है कि बस कुछ अजीब मोड़ नहीं है, लेकिन enums के एक जानबूझकर उपयोग किया सुविधा - पर विचार कैसे गणन मान अक्सर एक साथ ored कर रहे हैं पैक करने के लिए उन्हें एक ही मूल्य में, या 0 पास किया जाता है जब कोई भी गणना लागू नहीं होती है।

सी ++ 03 में, यह स्पष्ट प्रोग्रामर नियंत्रण में नहीं है कि संकलक द्वारा बैकिंग पूर्णांक का कितना बड़ा उपयोग किया जाएगा, लेकिन सीमा 0 और स्पष्ट रूप से सूचीबद्ध गणनाओं की अवधि की गारंटी है।

तो, यह जरूरी नहीं है कि 10 animal के लिए वैध, मूल्यवान मूल्य नहीं है। भले ही बैकिंग वैल्यू उस अभिन्न मूल्य को स्टोर करने के लिए पर्याप्त नहीं था, जिसे आप animal में कनवर्ट करने का प्रयास कर रहे हैं, एक संकुचित रूपांतरण लागू किया जा सकता है - आम तौर पर यह कम से कम महत्वपूर्ण बिट्स का उपयोग करेगा जो एनम बैकिंग प्रकार पकड़ सकता है, छोड़ना कोई अतिरिक्त उच्च आदेश बिट्स, लेकिन विवरण के लिए मानक की जांच करें।

प्रैक्टिस में, पीसी और सर्वर हार्डवेयर पर सबसे आधुनिक सी ++ 03 कंपाइलर्स गणना के लिए एक (32 बिट) int का उपयोग करने के लिए डिफ़ॉल्ट रूप से डिफ़ॉल्ट हैं, क्योंकि सी लाइब्रेरी फ़ंक्शंस में कॉल करने में सुविधा होती है जहां 32 बिट मानक हैं।

मैं कभी एक संकलक को अपवाद फेंकने की उम्मीद करता हूं जब static_cast<> का उपयोग करके किसी भी मूल्य को enum में shoehorned किया जाता है।

संबंधित मुद्दे