2016-01-13 2 views
8

http://www.cplusplus.com/reference/cstdlib/strtol/ के अनुसार इस फ़ंक्शन में long int strtol (const char* str, char** endptr, int base) का हस्ताक्षर है।आप स्ट्रेटोल को कॉन्स्ट-सुधार के तहत कैसे कार्यान्वित करते हैं?

मुझे आश्चर्य है, हालांकि: यदि यह स्ट्रिंग की शुरुआत में const char * पारित हो जाता है, तो यह धोखाधड़ी के बिना पहले अप्रसन्न चरित्र में गैर-कॉन्स्ट पॉइंटर में कैसे बदल सकता है? स्ट्रैटोल दिखने का कार्यान्वयन क्या होगा जो const_cast नहीं करता है?

+0

आधार 'str' दिशा के रूप में ऑफसेट के साथ "खेलना" के बारे में क्या? – kazbeel

+3

यह 'const char ** endptr' लेगा और अन्यथा समान कार्यान्वयन होगा, लेकिन http://stackoverflow.com/questions/993700/are-strtol-strtod-unsafe देखें क्यों नहीं। –

+2

उत्तर "यह नहीं कर सकता" है। हालांकि, इसका उत्तर एक और सामान्य प्रश्न में दिया गया है। – dasblinkenlight

उत्तर

2

अधिकतर यह केवल कास्टिंग का उपयोग करता है।

ऐसे संख्यात्मक कार्य हैं जिनके पास मानक पुस्तकालय में समान संपत्ति है। सादगी पर सैक्रिफाइंग प्रकार की सुरक्षा संभावित कारण है, क्योंकि आप सी ++ में कार्यों को अधिभारित नहीं कर सकते हैं।

वे उम्मीद करते हैं कि प्रोग्रामर जिम्मेदारी लेता है, और endptr संपादित नहीं करता है, उदाहरण के लिए, str उदाहरण के लिए, एक स्ट्रिंग शाब्दिक है।

इसकी सीमित प्रकार प्रणाली के साथ, सी व्यावहारिक लोगों के लिए व्यावहारिक भाषा है।

1

strtolconst_cast (या समतुल्य) करता है। const दूर कास्टिंग कोई समस्या नहीं है, परिणामी सूचक का उपयोग मूल रूप से संशोधित करने के लिए- const पॉइंट हो सकता है।

लेकिन strtol बस इस सूचक को आपके साथ छेड़छाड़ किए बिना लौटाता है, इसलिए सब कुछ ठीक है।

+1

सबकुछ ठीक नहीं है। एक स्ट्रेटर को 'स्ट्रेटोल' में पॉइंटर पास करना संभव है, और परिणामी '* एंडप्टर 'पॉइंटर का उपयोग उस सरणी को संशोधित करने के लिए (प्रयास करने के लिए) करें, सभी कास्ट का उपयोग किए बिना। यह सी मानक पुस्तकालय में एक दोष है। –

+0

@ किथ थॉम्पसन एक ट्रेडऑफ बनाया गया है, और एक बेहतर इंटरफ़ेस के पक्ष में कुछ प्रकार की सुरक्षा को हटा दिया गया है। फिर भी, मानक के परिप्रेक्ष्य से, सबकुछ ठीक है: कोई यूबी या अन्य खतरे नहीं। – Quentin

+0

मेरे उत्तर में उदाहरण प्रोग्राम देखें। फ़ंक्शन स्वयं 'कॉन्स्ट' सुरक्षा का उल्लंघन नहीं करता है, लेकिन यह उपयोगकर्ता कोड को सक्षम बनाता है जो इसे कास्ट या चेतावनी के बिना ऐसा करने के लिए उपयोग करता है। एक बेहतर इंटरफ़ेस दो अलग-अलग फ़ंक्शंस प्रदान करेगा, एक 'const' डेटा के लिए और एक गैर-'const' डेटा के लिए। –

1

आप स्ट्रेटोल को कॉन्स्ट-सुधार के तहत कैसे कार्यान्वित करते हैं? सी 11 _Generic की

उपयोग समान होगा के रूप में केवल समारोह हस्ताक्षर संरक्षण की जरूरत है, कोड

// when passed argument for `str` is `char *` and for `endptr` is `char **` 
long strotol(const char* str, char** endptr, int base); 
// or 
// when passed argument for `str` is `const char *` and for `endptr` is `const char **` 
long strotol_c(const char* str, const char** endptr, int base); 
// and warn/error otherwise 

कार्यान्वयन के दोनों फोन करने की अनुमति होगी के रूप में नीचे। चूंकि यह strtol() से अलग है, इसलिए इसे strtol_s() जैसे कुछ और कहा जाना चाहिए।

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

long int strtol_c(const char * restrict nptr, const char ** restrict endptr, int base) { 
    return strtol((char *) nptr, (char **) endptr, base); 
} 

#define strtol_s(n,e,b) _Generic(n, \ 
    char *: strtol((n), (e), (b)), \ 
    const char *: strtol_c((n), (e), (b)), \ 
    default: 0 \ 
) 

int main(void) { 
    char *src = malloc(100); 
    strcpy(src, "456"); 
    const char *srcc = "123"; 
    char *endptr; 
    const char *endcptr; 
    long L[6] = { 0 }; 

    // OK - matching str and *endptr 
    L[0] = strtol_s(src, &endptr, 0); 

    // warning: passing argument 2 of 'strtol' from incompatible pointer type 
    L[1] = strtol_s(src, &endcptr, 0); 

    // warning: passing argument 2 of 'strtol_c' from incompatible pointer type 
    L[2] = strtol_s(srcc, &endptr, 0); 

    // OK - matching str and *endptr 
    L[3] = strtol_s(srcc, &endcptr, 0); 

    L[4] = strtol(src, &endptr, 0); 
    // warning passing argument 2 of 'strtol' from incompatible pointer type 

    // OK 
    L[5] = strtol(src, &endcptr, 0); 
    return !L[0]; 
} 

क्या खो दिया है: strtol_s(), एक सच्चे कार्य नहीं है, तो यह करने के लिए एक सूचक नहीं बनाया जा सकता।

यह धोखाधड़ी के बिना पहले अप्रसन्न चरित्र में गैर-कॉन्स्ट पॉइंटर में बदलने का प्रबंधन कैसे करता है?

strtol(), हालांकि यह दूसरा तर्क के रूप में एक char **endptr लेता है, *endptr संशोधित नहीं करता है।

4

आप strtol को कॉन्स्ट-सुधार के तहत कैसे कार्यान्वित करते हैं? क्योंकि strtol की परिभाषा स्वाभाविक const -correct नहीं है

आप नहीं करते हैं,।

यह सी मानक पुस्तकालय में एक दोष है।

कई मानक कार्यों कि एक const char* तर्क और एक गैर constchar* सूचक है कि सरणी संशोधित करने के लिए इस्तेमाल किया जा सकता वापस देना (एक चरित्र सरणी की शुरुआत बात करने के लिए उम्मीद) ले रहे हैं।

char *strchr(const char *s, int c); 

उदाहरण के लिए::

#include <string.h> 
int main(void) { 
    const char *s = "hello"; 
    char *ptr = strchr(s, 'h'); 
    *ptr = 'H'; 
} 

इस कार्यक्रम अपरिभाषित है व्यवहार

strchr एक उदाहरण है। मेरे सिस्टम पर, यह एक सेगमेंटेशन गलती के साथ मर जाता है।

समस्या strchr में ही नहीं होती है। यह वादा करता है कि आप जिस स्ट्रिंग को पास करते हैं उसे संशोधित न करें, और ऐसा नहीं होता है। लेकिन यह एक सूचक देता है कि कॉलर तब इसे संशोधित करने के लिए उपयोग कर सकता है।

ANSI C समिति 1980 के अंत में वापस, दो संस्करणों, गैर const सरणियों के लिए एक है कि const चरित्र सरणियों पर काम करता है और दूसरे में ऐसे प्रत्येक समारोह विभाजित किया जा सकता था:

char *strchr(char *s, int c); 
const char *strcchr(const char *s, int c); 

लेकिन जो मौजूदा प्री-एएनएसआई कोड तोड़ दिया होगा, const से पहले लिखा गया था। यही कारण है कि सी ने स्ट्रिंग अक्षर const नहीं बनाया है।

सी ++, जो सी के अधिकांश मानक पुस्तकालय को विरासत में मिला है, कुछ कार्यों के अधिभारित संस्करण प्रदान करके इसका समाधान करता है।

नीचे पंक्ति यह है कि आप, सी प्रोग्रामर के रूप में, const के रूप में परिभाषित वस्तुओं को संशोधित करने के लिए ज़िम्मेदार नहीं हैं। ज्यादातर मामलों में, भाषा आपको इसे लागू करने में मदद करती है, लेकिन हमेशा नहीं।

के लिए कैसे इन कार्यों const डेटा के लिए एक गैर const सूचक वापस जाने के लिए प्रबंधन के रूप में, वे शायद सिर्फ एक डाली आंतरिक रूप से (न कि किसी const_cast है, जो केवल C++ मौजूद है) का उपयोग करें। ऐसा लगता है कि वे सी में लागू किए गए हैं, जो संभवतः लेकिन आवश्यक नहीं है।

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