2012-09-24 14 views
8

यदि किसी कंपाइलर के पास एक निश्चित प्रकार (उदा। Ptrdiff_t) एक एम्बेडेड प्रकार के रूप में है, तो मैं इसे फिर से टाइप नहीं करना चाहता हूं। मुझे पता है कि नीचे कोड ठीक से काम नहीं करता है जो मुझे उम्मीद थी।मैं सी संकलक में पहले से परिभाषित एक निश्चित प्रकार की जांच कैसे कर सकता हूं?

#ifndef ptrdiff_t 
    typedef long int ptrdiff_t; 
#endif 

मैं एक खास प्रकार पहले से ही सी संकलक में परिभाषित किया गया है कैसे देख सकते हैं?

+1

आपके विशेष मामले में। ptrdiff_t को हमेशा परिभाषित किया जाना चाहिए यदि आप stddef.h –

+2

अस्तित्व के लिए कोड में परीक्षण करने में सक्षम होने और विशेष परिभाषाओं के गुणों को "प्रतिबिंब" कहा जाता है। स्क्रिप्टिंग भाषाएं पूर्ण प्रतिबिंब का समर्थन करती हैं, आंशिक रूप से क्योंकि यह स्क्रिप्टिंग भाषाओं के लिए अपेक्षाकृत आसान है। .NET और JVM समर्थन प्रतिबिंब भी। देशी भाषाओं के लिए, हालांकि, रन-टाइम प्रतिबिंब का समर्थन करने के लिए बहुत अधिक निष्पादन योग्य कोड की आवश्यकता होगी। कुछ संकलन-समय प्रतिबिंब को उस ओवरहेड के बिना समर्थित किया जा सकता है, लेकिन सी संकलन समय पर भी लगभग कोई प्रतिबिंब समर्थन नहीं है। – Steve314

+0

cmake या autotools जैसे टूल का उपयोग करें – szx

उत्तर

1

अपने प्रश्न में आप थोड़ा 2 अलग अलग चीजें भ्रमित कर रहे हैं: ये stnd प्रकार के होते हैं और वे परिभाषित कर रहे हैं आदि

प्रकार में बनाया, int, float की तरह, सभी compilers है। __int64 जैसे मानक मानक नहीं हैं, लेकिन इन्हें कुछ कंपाइलरों में परिभाषित किया गया है। आपको उनका उपयोग करने के लिए कुछ भी करने की ज़रूरत नहीं है। साथ ही यदि आप परिभाषित हैं या नहीं तो आप अपने कोड में नहीं समझ सकते हैं। यह केवल संकलक पर दस्तावेज़ों से पता लगाया जा सकता है। आप लिख सकते हैं:

#ifdef MSVC 
     .... Microsoft specific code 
#else 
     .... Code for other compiler. 
#endif 

यह दृष्टिकोण आप compiler independent environment की तरह बनाने के लिए अनुमति देता है।

निर्मित प्रकारों के अलावा, शीर्षलेखों से आने वाले प्रकार भी हैं। कुछ शीर्षकों की संरचनाएं होती हैं:

#ifndef ptrdiff_t_DEFINED 
    #define ptrdiff_t_DEFINED 
    typedef long int ptrdiff_t; 
#endif 

ध्यान दें कि मैक्रोप्रोसेसर defn प्रकार के defn से अलग रहता है। आप यह जांच नहीं सकते कि किस प्रकार को परिभाषित किया गया है या नहीं, लेकिन आप आसानी से जांच सकते हैं कि परिभाषा परिभाषित की गई है या नहीं।

आपके कोड में कौन से शीर्षलेख शामिल हैं, आप स्वयं को मानते हैं। इसका मतलब है कि ये परिभाषा in the compiler itself नहीं हैं। वे वर्तमान अनुवाद इकाई की परिभाषाओं के सेट में हैं। कंपाइलर के लिए उन्हें आपके स्वयं के कोड में लिखने वाली अन्य प्रकार की परिभाषाओं से थोड़ा अंतर होता है।

कुछ कंपाइलर या सिस्टम शीर्षलेखों के ऊपर उपरोक्त उदाहरण में "रक्षा रक्षा" नहीं है। इस मामले में आप केवल एक चीज जो ट्रैक कर सकते हैं, यह ट्रैक करना है कि हेडर क्या आ रहे हैं और इन हेडर को शामिल नहीं करते हैं/शामिल नहीं हैं, कथन के आसपास अपने #ifdef गार्ड का उपयोग करके मैबी शामिल हैं।

5

सामान्य रूप से ऐसा करने का कोई तरीका नहीं है। कुछ मामलों में एक मैक्रो हो सकता है जिसे उसी समय परिभाषित किया गया है जिसे आप उपयोग कर सकते हैं।

अपने विशेष उदाहरण में, आप #include <stddef.h> कर सकते हैं, जो हमेशा ptrdiff_t को परिभाषित करना चाहिए।

0

एक सी भाषा आरक्षित निर्माण को फिर से परिभाषित करने के बाद आम तौर पर एक संकलन समय त्रुटि का कारण बनता है, इसे सामान्य रूप से जांचना संभव नहीं है। यदि आप रुचि रखते हैं (अकादमिक/सीखने की प्रक्रिया के लिए), तो आप अपने सी प्रोग्राम पर अपवाद/त्रुटियों की जांच के लिए एक मूल कंपाइलर पास लिख सकते हैं ताकि यह पता लगाया जा सके कि कोई प्रकार आरक्षित है या नहीं।

4

जैसा कि अन्य ने कहा है, इसका कोई अच्छा सामान्य समाधान नहीं है। टाइप नाम प्रीप्रोसेसर को दिखाई नहीं दे रहे हैं, इसलिए आप उनके अस्तित्व के परीक्षण के लिए #ifdef का उपयोग नहीं कर सकते हैं।

हालांकि कई आंशिक समाधान हैं, और वे इस बात पर निर्भर करते हैं कि किसी दिए गए प्रकार की आवश्यकताएं कहां से आईं।

1 99 0, 1 999 और 2011 में जारी आईएसओ सी मानक के कई संस्करण हैं।प्रत्येक नया मानक (सिद्धांत में) पिछले एक को पीछे छोड़ देता है और बदलता है, और प्रत्येक एक नए प्रकार को परिभाषित करता है। उदाहरण के लिए 1 999 सी मानक हेडर <stdbool.h> और <stdint.h>, और bool, int32_t, आदि टाइप करें। यदि आप bool प्रकार का उपयोग करना चाहते हैं, लेकिन फिर भी चाहते हैं कि आपका कोड उन कार्यान्वयन के लिए पोर्टेबल हो जो सी 99 का समर्थन नहीं करते हैं, तो आप कुछ कर सकते हैं जैसे:

#if defined(__STDC__) && __STDC_VERSION__ >= 199901L 
#include <stdbool.h> 
#else 
typedef enum { false, true } bool; 
#endif 

enum प्रकार से व्यवहार नहीं करता है बिल्कुल तरह C99 के अंतर्निहित bool प्रकार है, तो आप एक छोटे से कैसे आप इसका इस्तेमाल में सावधान रहने की जरूरत है।

uintptr_t टाइप <stdint.h> में परिभाषित वैकल्पिक है। यह एक हस्ताक्षरित प्रकार है जो जानकारी के नुकसान के बिना परिवर्तित void* सूचक मूल्य धारण कर सकता है; एक कार्यान्वयन जिसमें ऐसा कोई हस्ताक्षरित प्रकार नहीं है (कहें, क्योंकि पॉइंटर्स किसी भी पूर्णांक प्रकार से बड़े होते हैं) इसे प्रदान नहीं करेंगे। आप सीधे प्रकार खुद के लिए परीक्षण नहीं कर सकते, लेकिन आप मैक्रो कि अपनी सीमा देने के लिए परीक्षण कर सकते हैं:

#include <stdint.h> 

#ifdef UINTMAX_MAX 
/* uintmax_t exists */ 
#else 
/* uintmax_t doesn't exist */ 
#endif 

आप __STDC__ और __STDC_VERSION__ के लिए एक परीक्षण में इस रैप करने के लिए यदि आप C99 कल्पना नहीं कर सकते आवश्यकता हो सकती है या और अच्छा।

प्रकार long long एक पूर्वनिर्धारित प्रकार (लाइब्रेरी का हिस्सा नहीं है), सी 99 में जोड़ा गया है। फिर, आप इसके लिए सीधे परीक्षण नहीं कर सकते, लेकिन आप मैक्रो कि अपनी सीमा को परिभाषित करने के लिए परीक्षण कर सकते हैं:

#include <limits.h> 

#ifdef LLONG_MAX 
/* long long exists */ 
#else 
/* long long *probably* doesn't exist */ 
#endif 

अंत में, वहाँ बातें आप सीधे सी में ऐसा नहीं कर सकते हैं, लेकिन आप के रूप में कर सकते हैं कि आपके कार्यक्रम की निर्माण प्रक्रिया का हिस्सा। उदाहरण के लिए, POSIX POSIX- विशिष्ट शीर्षलेख <unistd.h> में एक प्रकार pid_t परिभाषित करता है (यह एक प्रक्रिया पहचानकर्ता का प्रकार है, getpid() फ़ंक्शन द्वारा लौटाया गया है)। आप सशर्त एक हैडर शामिल नहीं कर सकते हैं - लेकिन आप एक छोटा सा कार्यक्रम है कि यदि शीर्ष लेख मौजूद नहीं है संकलित करने के लिए असफल हो जायेगी लिख सकते हैं:

#include <unistd.h> 
pid_t dummy; 

अपने निर्माण की प्रक्रिया के हिस्से के रूप में, इस फाइल को संकलित करने के लिए प्रयास करें। यदि यह सफल होता है, तो

#define HAVE_PID_T 

कॉन्फ़िगरेशन हेडर पर एक पंक्ति संलग्न करें; अगर यह विफल रहता है, जैसे

#undef HAVE_PID_T 

अपने स्रोत कोड में एक लाइन संलग्न की है तो उन्हें तरह कुछ लिख सकते हैं:

#include "config.h" 
#ifdef HAVE_PID_T 
#include <unistd.h> 
/* pid_t exists */ 
#else 
/* pid_t doesn't exist */ 
#endif 

GNU Autoconf परीक्षण के इस प्रकार स्वचालित करने के लिए एक तरीका प्रदान करता है, लेकिन यह करने के लिए आलोचना की गई है अत्यधिक जटिल और अनावश्यक होने के नाते।

यह सब मानते हैं कि, एक बार जब आप यह निर्धारित कर लें कि कोई प्रकार मौजूद है, तो आप उस जानकारी के साथ कुछ उपयोगी कर सकते हैं। कुछ प्रकार के लिए, जैसे bool, आप लगभग बराबर विकल्प लागू कर सकते हैं। दूसरी ओर, pid_t के लिए, संभवतः एक अच्छा फॉलबैक नहीं है, जब तक आप प्रक्रियाओं से संबंधित सभी कोड को #ifdef निकाल दें। यदि आपका प्रोग्राम सिर्फ उस सिस्टम पर काम नहीं करेगा जिसमें pid_t और getpid() नहीं है, तो यह संभवतः कोड लिखना सर्वोत्तम होगा जो मानता है कि वे मौजूद हैं। यदि आप अपने कोड को उस सिस्टम पर संकलित करने का प्रयास करते हैं जो उन्हें प्रदान नहीं करता है, तो यह तुरंत संकलित करने में असफल हो जाएगा, और यह सबसे अच्छी बात हो सकती है जो आप कर सकते हैं।

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

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