2015-03-05 13 views
26

निम्नलिखित स्निपेट बजना 3.5 में ठीक काम करता है, लेकिन नहीं जीसीसी 4.9.2 में:क्या समेकित अस्थिर के साथ जोड़ा जा सकता है?

int main() 
{ 
    constexpr volatile int i = 5; 
} 
त्रुटि के साथ

:

error: both 'volatile' and 'constexpr' cannot be used here

अगर मैं विधानसभा कि बजना उत्पन्न करता है का निरीक्षण किया, यह 5 से पता चलता अपेक्षा के अनुरूप:

movl $5, -4(%rsp) 

जीसीसी में, constexpr int i = 5 दूर अनुकूलित है, लेकिन volatile int i = 5 भी ०१२३७९०७५८६ से पता चलता विधानसभा में। volatile const int i = 5 दोनों कंपाइलरों में संकलित करता है। यह एक ही समय में अस्थिर और स्थिर दोनों होने के लिए एक विदेशी अवधारणा नहीं है।

कौन सा संकलक मानकों द्वारा सही है?

+0

क्या है यह आप को व्यक्त करने की कोशिश कर रहे हैं? वे अनिवार्य रूप से विरोध कर रहे हैं। इसे सेट करने के बाद निरंतर कभी भी नहीं बदलेगा, लेकिन एक अस्थिरता सभी को बदलने की गारंटी है (संभवतया किसी अन्य धागे से भी)। – TheBuzzSaw

+2

'constexpr' और' const' समान नहीं हैं –

+9

@TheBuzzSaw: 'अस्थिर 'का अर्थ यह नहीं है कि कुछ भी बदलने की प्रवृत्ति है। इसका मतलब यह है कि स्मृति पहुंच के दुष्प्रभाव हो सकते हैं, और इसलिए संकलक को I/O के रूप में इसका इलाज करना चाहिए। जब भी स्थिर रहने के लिए मूल्य की गारंटी दी जाती है तब भी सिस्टम पर 'अस्थिर' का उपयोग करना आवश्यक हो सकता है। – Mehrdad

उत्तर

23

हाँ, यह है, वहाँ defect report 1688: Volatile constexpr variables है कि इस के लिए दायर किया गया था और कहा था मान्य है:

There does not appear to be language in the current wording stating that constexpr cannot be applied to a variable of volatile-qualified type. Also, the wording in 5.19 [expr.const] paragraph 2 referring to “a non-volatile object defined with constexpr” might lead one to infer that the combination is permitted but that such a variable cannot appear in a constant expression. What is the intent?

इसे अस्वीकार कर दिया गया था नहीं एक दोष (NAD) के रूप में, प्रतिक्रिया और तर्क था:

The combination is intentionally permitted and could be used in some circumstances to force constant initialization.

डॉ तरह के एक चर बताते ही नहीं है

constexpr volatile int i = 5;  
constexpr int y = i ;   // Not valid since i is volatile 

धारा [expr: एक निरंतर अभिव्यक्ति में प्रयोग करने योग्य।स्थिरांक]/2 एक सशर्त अभिव्यक्ति सहित नहीं एक कोर निरंतर अभिव्यक्ति करता है कि सभी मामलों में शामिल हैं:

an lvalue-to-rvalue conversion (4.1) unless it is applied to

और सभी अपवाद की आवश्यकता होती है:

[...]that refers to a non-volatile [...] object [...]

+1

मुझे पता था * एक डीआर होना था, लेकिन एक नहीं मिला। बहुत बढ़िया। – Casey

17

का हवाला देते हुए N4140 [dcl.constexpr]/9:

A constexpr specifier used in an object declaration declares the object as const . Such an object shall have literal type and shall be initialized.

शाब्दिक प्रकार/10 में [basic.types] परिभाषित किया गया है:

A type is a literal type if it is:

(10.1) — void ; or

(10.2) — a scalar type; or

(10.3) — a reference type; or

(10.4) — an array of literal type; or

(10.5) — a class type (Clause 9) that has all of the following properties:

(10.5.1) — it has a trivial destructor,

(10.5.2) — it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and

(10.5.3) — all of its non-static data members and base classes are of non-volatile literal types.

अदिश प्रकार पैरा 9 में है:

Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), std::nullptr_t , and cv-qualified versions of these types (3.9.3) are collectively called scalar types.

int अंकगणितीय है, इसलिए volatile int एक स्केलर प्रकार है और इसलिए एक शाब्दिक प्रकार है। constexpr volatile int i = 5; इस प्रकार एक अच्छी तरह से घोषित घोषणा है।

दिलचस्प है, एक अभिव्यक्ति है कि मूल्यांकन करता i एक कोर-निरंतर अभिव्यक्ति नहीं किया जा सकता क्योंकि यह अस्थिर प्रकार का एक glvalue ([expr.const]/2) के लिए एक lvalue करने वाली rvalue रूपांतरण लागू होता है। नतीजतन, i का मूल्यांकन करने वाले अभिव्यक्ति न तो अभिन्न स्थिर अभिव्यक्ति और न ही निरंतर अभिव्यक्ति हैं। मुझे यकीन नहीं है कि constexpr उस घोषणा में i को const, और (@T.C. पर ध्यान दें) को इसके प्रारंभिक अभिव्यक्ति के लिए निरंतर अभिव्यक्ति होने की आवश्यकता है।

मैंने इसे GCC bug 65327 के रूप में रिपोर्ट किया है, हम देखेंगे कि जीसीसी लोगों को क्या कहना है।

2015-03-16 अपडेट: बग जीसीसी के लिए तय किया गया है 5.

+0

"गैर-अस्थिर" की उपस्थिति (10.5।3) मुझसे कहता है कि कम से कम कुछ हद तक संभावना है कि मानक सामान्य रूप से अस्थिर-योग्य प्रकारों को बाहर करने के लिए मानक था, और यह एक निरीक्षण था। – Hurkyl

+4

"मुझे यकीन नहीं है कि उस घोषणा में कॉन्स्टेक्सर का मुझे कोई प्रभाव नहीं होने से परे कोई प्रभाव पड़ता है।" - यह अभी भी एक स्थिर अभिव्यक्ति होने के लिए प्रारंभकर्ता को बाधित करता है। –

+0

इसके लायक होने के लिए, यहां [पैच] (http://patchwork.ozlabs.org/patch/173189/) है जो इस त्रुटि को पेश करता है। Wandbox पर परीक्षण से पता चलता है कि त्रुटि 4.5.4 और 4.6.4 के बीच पेश की गई थी। – user4637702

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

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