क्षमा करें अगर यह पहले पूछा गया है। मैंने इंटरनेट पर खोज की और जवाब नहीं मिला।

मान लें कि मेरे पास एक फ़ाइल है Common.h, और A.cpp और B.cpp में Common.h शामिल हैं।

अगर मैं Common अनुवाद इकाई में एक वैश्विक const char * रखना चाहता हूं, तो मुझे इसे extern Common.h में बनाना होगा, और इसे Common.cpp में परिभाषित करना होगा। अन्यथा, यदि मैं केवल const char * MSG = "Hello World"; को Common.h में परिभाषित करता हूं, तो मुझे संकलन के दौरान एक duplicate symbol त्रुटि मिलती है।

हालांकि, अगर मैं Common.h में const int CONSTANT = 10; जैसे कथन के साथ वैश्विक कॉन्स्ट int को परिभाषित करता हूं तो कोड डुप्लिकेट प्रतीक त्रुटि के बिना संकलित होता है, और सब कुछ ठीक काम करता है।

मैं उलझन में हूं कि ऐसा क्यों है। मुझे यहाँ ऐसा लगता है कि उपरोक्त दो उदाहरणों के बीच एकमात्र अंतर प्रकार है, जो मुझे लगता है कि इससे कोई फर्क नहीं पड़ना चाहिए। मुझे सी-स्ट्रिंग्स के लिए डुप्लिकेट प्रतीक त्रुटि क्यों मिलती है, लेकिन इनट्स नहीं?

मान लीजिए main.cpp, A.h, B.h, A.cpp, और B.cpp इस तरह दिखते हैं:

// A.h
#pragma once
void f();
// A.cpp
#include "A.h"
#include "Common.h"

#include <iostream>

void f() {
    std::cout << MSG << std::endl;
}
// B.h
#pragma once
void g();
// B.cpp
#include "B.h"
#include "Common.h"

#include <iostream>

void g() {
    std::cout << CONSTANT << std::endl;
}
// main.cpp
#include "A.h"
#include "B.h"

int main()
{
    f();
    g();
}

अब, मान लीजिए कि हम कमांड g++ main.cpp A.cpp B.cpp Common.cpp -std=c++14 के साथ कंपाइल करते हैं।

यदि हम Common.h और Common.cpp को निम्नलिखित बनाते हैं, तो संकलन त्रुटि duplicate symbol MSG के साथ विफल हो जाता है:

// Common.h
#pragma once
const char * MSG = "Hello World";
const int CONSTANT = 10; // defined in header file
// Common.cpp
// empty

हालांकि, यह संकलित करता है:

// Common.h
#pragma once
extern const char * MSG;
const int CONSTANT = 10; // defined in header file
// Common.cpp
#include "Common.h"
const char * MSG = "Hello World";

मैं सोच रहा हूं कि हमें स्ट्रिंग के लिए बाहरी और अलग परिभाषा और घोषणा की आवश्यकता क्यों है, लेकिन int के लिए नहीं।

किसी ने सी-स्ट्रिंग प्रकार को const char * के बजाय const char * const के रूप में बनाने का सुझाव दिया। पॉइंटर कास्ट क्यों काम करता है? साथ ही, इस मामले में, इस समाधान और ऊपर दिए गए समाधान के बीच क्या अंतर है (जहां हम इसके बजाय स्ट्रिंग बाहरी बनाते हैं और परिभाषा/घोषणा विभाजित करते हैं)? दोनों विधियाँ संकलन त्रुटि का समाधान क्यों करती हैं और विधियों में क्या अंतर है?

मैंने यह भी देखा कि अगर मैं const int को केवल int में बदल देता हूं, तो मुझे फिर से duplicate symbol त्रुटि मिलती है। मुझे ऐसा लगता है कि इसके पीछे का कारण मेरे ऊपर दिए गए सवालों के जवाब से जुड़ा है। यह एक केस क्यों है?

2
Tony Bai 11 सितंबर 2020, 07:11

1 उत्तर

सबसे बढ़िया उत्तर

यह C और C++ के अंतरों में से एक है।

C++ में एक const वैरिएबल परोक्ष रूप से static है, यानी केवल वर्तमान अनुवाद इकाई के लिए दृश्यमान है। सी में यह पूरी तरह से extern है जो पूरे कार्यक्रम के लिए दृश्यमान है (जो सी और सी ++ दोनों में अन्य गैर-कॉन्स्ट घोषणाओं के लिए भी डिफ़ॉल्ट है)।

यह आपके अवलोकन की व्याख्या करता है।

नोट: एक const char *p चर की घोषणा एक const चर नहीं है। इसका मतलब है कि यह एक कॉन्स्टेबल वैरिएबल की ओर अंक है (यानी *p को संशोधित नहीं किया जा सकता है), लेकिन p खुद const नहीं है। तो यहां व्यवहार अलग है। const char * const p एक कॉन्स्टेबल डिक्लेरेशन होगा।

4
Andreas H. 11 सितंबर 2020, 09:21