2015-03-04 4 views
8

मैंने कई constexpr कार्यों को लिखा है और कुछ संसाधन सीमाओं को नियंत्रित करने के लिए static_asserts में उनका उपयोग किया है। लेकिन मैं न केवल संकलन-समय भविष्यवाणी को लागू करना चाहता हूं बल्कि सामान्य संकलन प्रक्रिया के दौरान गणना की गई वास्तविक मानों को भी देखना चाहता हूं या कम से कम जब दावा विफल हो जाता है।सी ++ में संकलन-समय गणना के परिणाम को प्रिंट कैसे करें?

संकलन के दौरान स्ट्रिंग संदेशों को मुद्रित करने के तरीके हैं, लेकिन कॉन्टेक्सप्र कंप्यूटेशंस के प्रिंटिंग परिणामों के बारे में क्या है?

+3

शर्म 'static_assert' का संदेश तर्क यह नहीं कर सकता है। –

+2

आप हालत विफलता पर अपूर्ण प्रकार को मजबूर कर नियमित संकलक डायग्नोस्टिक्स का उपयोग कर सकते हैं, जो संकलक आउटपुट में दिखाई देने वाले टेम्पलेट तर्कों का कारण बन सकता है, [जैसे यहां] (http://coliru.stacked-crooked.com/a/ d2a8871788e97987) –

+0

मैं इसे वीसी ++ के साथ कर सकता हूं (मेरा जवाब देखें)। शायद कोई यह देखने का प्रयास कर सकता है कि जीसीसी – JavaMan

उत्तर

5

यहां कुछ कोड है जो एक संदेश संदेश के बाद ब्याज के मूल्यों को मुद्रित करने के लिए जीसीसी के नैदानिक ​​संदेशों का शोषण करता है। ब्याज की मूल्यों को खोजने के लिए, आप केवल T x = के लिए त्रुटि स्ट्रिंग खोज करने के लिए की जरूरत है:

g++ h.cpp -std=c++11 h.cpp: In instantiation of ‘constexpr void my_assert() [with bool B = false]’: h.cpp:16:34: required from ‘f() [with int X = 4]::__lambda0::__lambda1’ h.cpp:15:35: required from ‘struct f() [with int X = 4]::__lambda0::__lambda1’ h.cpp:16:38: required from ‘f() [with int X = 4]::__lambda0’ h.cpp:14:28: required from ‘struct f() [with int X = 4]::__lambda0’ h.cpp:16:41: required from ‘void f() [with int X = 4]’ h.cpp:21:10: required from here h.cpp:9:5: error: static assertion failed: oh no static_assert(B, "oh no"); ^ h.cpp:4:6: error: ‘void transparent(F) [with T = long int; T x = 64l; F = f() [with int X = 4]::__lambda0::__lambda1]’, declared using local type ‘f() [with int X = 4]::__lambda0::__lambda1’, is used but never defined [-fpermissive] void transparent(F f) { f(); } ^ h.cpp:4:6: error: ‘void transparent(F) [with T = int; T x = 11; F = f() [with int X = 4]::__lambda0]’, declared using local type ‘f() [with int X = 4]::__lambda0’, is used but never defined [-fpermissive]

ध्यान दें कि भागों

+0

में एक ही तकनीक का उपयोग किया जा सकता है, धन्यवाद! किसी भी विचार को चेतावनी संदेश कैसे निकालना है ताकि संकलन जारी रहे? –

0
बोल्ड:

#include <string> 

template <class T, T x, class F> 
void transparent(F f) { f(); } 


template <bool B> 
constexpr void my_assert() { 
    static_assert(B, "oh no"); 
} 

template <int X> 
void f() { 
    transparent<int, X+7>([]{ 
     transparent<long, X*X*X>([]{ 
      my_assert<X+10==-89>(); });}); 
} 

int main() { 
// f<3>(); 
    f<4>(); 
// f<-99>(); 
} 

यहाँ त्रुटि है कि यह मुझे मिल गया है

मेरा वीसी ++ कोड जो प्रिंट करता है, संकलन के दौरान, जितना आप चाहते हैं उतने संकलन समय स्थिरांक का मूल्य (जैसे आकार संरचनाएं) और त्रुटि के बिना संकलन जारी रखें:

// cpptest.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
//#define VALUE_TO_STRING2(x) #x 
//#define VALUE_TO_STRING(x) VALUE_TO_STRING2(x) 


#define TO_STRING(x) #x 
#define FUNC_TEMPLATE_MSG(x,y) "[" x "]""["TO_STRING(y)"]" 

template<unsigned int N,unsigned int M> 
int printN() 
{ 
#pragma message(FUNC_TEMPLATE_MSG(__FUNCSIG__ ,1)) 

    return 0; 
}; 



struct X { 
    char a[20]; 
    int b; 
}; 
struct Y { 
    char a[210]; 
    int b; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
printN<sizeof(X),__COUNTER__>(); 
printN<sizeof(Y),__COUNTER__>(); 
//..as many compile time constants as you like 
} 

वीसी ++ 2010 द्वारा उत्पादित नमूना आउटपुट। लक्ष्य मान पहला फ़ंक्शन टेम्पलेट पैरामीटर मान (उदाहरण में 0x18 और 0xd8) है जिसे वीसी ++ ने विषम रूप से आउटपुट को हेक्साडेसिमल मान के रूप में चुना है !!

1>------ Build started: Project: cpptest, Configuration: Release Win32 ------ 
1> cpptest.cpp 
1> [int __cdecl printN<0x18,0x0>(void)][1] 
1> [int __cdecl printN<0xd8,0x1>(void)][1] 
1> Generating code 
1> Finished generating code 
1> cpptest.vcxproj -> c:\work\cpptest\Release\cpptest.exe 
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 

प्रमुख यहां इस्तेमाल तकनीक है कि एक प्रत्येक कार्य टेम्पलेट इन्स्टेन्शियशन दौरान, #pragma message() निर्देश एक बार शुरू हो जाती है है। माइक्रोसॉफ्ट विशिष्ट मैक्रो __FUNCSIG__ युक्त फ़ंक्शन के हस्ताक्षर को प्रदर्शित कर सकता है और इस प्रकार पूर्णांक मान फ़ंक्शन टेम्पलेट के प्रत्येक विशिष्ट तत्कालता में उपयोग किया जा सकता है। दूसरे टेम्पलेट पैरामीटर के रूप में COUNTER देना यह सुनिश्चित करना है कि एक ही मान के 2 पूर्णांक अभी भी अलग-अलग मानते हैं। #pragma निर्देश में 1 का कोई उपयोग नहीं है, लेकिन अगर हमारे पास 1 से अधिक ऐसे निर्देश हैं और आउटपुट विंडो गन्दा संदेशों से भरा है तो पहचानकर्ता के रूप में उपयोग किया जा सकता है।

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