2016-06-23 11 views
7

क्या निम्न कोड C++ में अच्छी तरह परिभाषित है? (*)अपूर्ण प्रकार के डेटा सदस्य को सूचक

मुझे यह पता लगाने में कठिनाई हो रही है कि मानक में भी कहां देखना है, और वेब पर खोज करना कुछ ठोस नहीं है।

struct S; 
struct T { 
    constexpr T() = default; 
    bool S::* a = nullptr; 
    int b  = 42; 
}; 
const T t{}; 
// Test. Compiled using: cl /W4 /WX /FAs filename.cpp 
#include <stdlib.h> 
int main() { 
    if (t.b != 42) abort(); 
} 

कारण मैं पूछ रहा हूँ क्योंकि यह काम करता है (या लगता है) जीसीसी और बजना (x86/x86_64) के नए संस्करण के साथ है, लेकिन विफल रहता है (**) विजुअल स्टूडियो 2015 के साथ है अद्यतन 2 और 3 को अपडेट करें आर सी।

एक बग की रिपोर्ट करने से पहले मैं यह सुनिश्चित करना चाहता हूं कि मैं अपरिभाषित व्यवहार पर निर्भर नहीं हूं या सिर्फ सही शर्तों की खोज नहीं कर रहा हूं।

मैंने /vmg और /vmb का उपयोग करने का भी प्रयास किया है जैसा कि this post में उल्लिखित है।

(*): मुझे ज्यादातर सी ++ 14 और बाद में परवाह है, लेकिन मुझे कोई कारण नहीं दिख रहा है कि उत्तर सी ++ 11 पर लागू नहीं होना चाहिए।
(**): यदि कोड अच्छी तरह से परिभाषित किया गया है तो यह एक कोडेजन बग जैसा दिखता है जहां यह सूचक के लिए आवंटन कक्ष नहीं है। struct S से struct S{} को बदलकर कोड "काम" लगता है।

+1

आप कोड को क्या करने की उम्मीद कर रहे हैं? क्या 'टी' में 'एस' के लिए एक सूचक होना चाहिए, और यदि हां, तो यह क्यों नहीं लिखा गया है 'एस * ए = नलप्टर;'? – Xirema

+0

संकलित [यहां] (http://rextester.com/NFYP31324) और अपने स्वयं के एमएसवीएस 2015 पर। मेरे पास संस्करण 14.0.23107.0 डी 14REL – NathanOliver

+1

@Xirema: 'T :: a' एक [boolter a (bool) डेटा है सदस्य] (http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_data_members) अपूर्ण प्रकार 'S' में। @NathanOliver: यह मेरे लिए भी संकलित करता है, लेकिन इसे निष्पादित करते समय 'abort'। – user786653

उत्तर

5

आपका कोड अच्छी तरह से परिभाषित किया गया है:

N4594 3,2/5

[...] एक वर्ग प्रकार टी पूरा होना चाहिए अगर:

  • (5,1) टाइप टी का एक ऑब्जेक्ट परिभाषित किया गया है (3.1), या
  • (5.2) टाइप टी के एक गैर स्थैतिक क्लास डेटा सदस्य घोषित हैं एड (9.2), या
  • (5,3) टी ऑब्जेक्ट प्रकार या एक नया अभिव्यक्ति (5.3.4) में सरणी तत्व प्रकार के रूप में प्रयोग किया जाता है, या
  • (5,4) एक lvalue करने वाली rvalue रूपांतरण टाइप टी (4.1), या
  • (5.5) की एक ऑब्जेक्ट का संदर्भ देने वाले ग्लैवल्यू पर लागू होता है जो टी (क्लॉज 4, 5.2.3, 5.2.7, 5.2 टाइप करने के लिए एक अभिव्यक्ति को परिवर्तित किया जाता है (या तो स्पष्ट रूप से या स्पष्ट रूप से) .9, 5.4), या
  • (5.6) एक अभिव्यक्ति जो शून्य सूचक स्थिर नहीं है, और सीवी शून्य * के अलावा अन्य प्रकार है, को में परिवर्तित करने के लिए टी को संदर्भित किया गया है या मानक रूपांतरण का उपयोग कर टी के संदर्भ में (Clau से 4), एक गतिशील_कास्ट (5.2.7) या static_cast (5.2.9), या
  • (5.7) कक्षा वर्ग एक्सेस ऑपरेटर प्रकार टी (5.2.5), या
  • की अभिव्यक्ति पर लागू होता है
  • (5,8) typeid ऑपरेटर (5.2.8) या sizeof ऑपरेटर (5.3.3) प्रकार टी के एक संकार्य को
  • (5,9) की वापसी प्रकार या तर्क प्रकार के साथ एक समारोह लागू किया जाता है, या प्रकार टी परिभाषित किया गया है (3.1) या (5.2.2) कहा जाता है, या
  • (5,10) प्रकार टी के एक आधार वर्ग के साथ एक वर्ग परिभाषित किया गया है (खंड 10), या
  • (5.11) प्रकार का एक प्रकार का टी (5.18), या
  • (5।12) प्रकार टी एक संरेखण अभिव्यक्ति (5.3.6), या
  • (5.13) एक अपवाद-घोषणा के प्रकार टी, टी के संदर्भ में, या टी (15.3) के सूचक के विषय है। उनमें से

कोई नहीं कहता है कि TT की सूचक करने वाली सदस्य घोषित करने के क्रम में पूरे होने की जरूरत है।

+0

धन्यवाद! मैं इस जवाब को एक दिन में स्वीकार करूंगा या तब तक जब तक कोई मानक में कहीं और विरोधी बयान नहीं ढूंढ सकता। – user786653

+0

@ user786653 निश्चित रूप से। – PcAF

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